LoginSignup
8
10

More than 5 years have passed since last update.

OkHttpを利用した画像取得方法(超簡易版)

Posted at

API23でapache関連のモジュールが軒並み使えなくなっていることに加え、Volleyが未だにapacheモジュールを利用していることを理由(他にもmavenリポジトリがないとか)に、通信ライブラリをOkHttpへ移行することをよく勧めています。

しかし単に勧めるだけというのも投げっぱなし感があるので、移行に伴う各種処理の記述方法についても、共有していこうと思いました。

というわけでタイトルにも書いてますが、OkHttpを利用した(http上の)画像取得方法の超簡易版です。

サンプルプロジェクトもアップしています。

該当コード

GetImageAsyncTask.java

/**
 * ResponseBodyの取得
 */
private static ResponseBody getResponse(@NonNull String url) {
    Timber.d("get url:%s", url);
    Request request = new Request.Builder().url(url).get().build();
    try {
        Response response = new OkHttpClient().newCall(request).execute();
        if (!response.isSuccessful()) {
            Timber.d("response error %d: %s", response.code(), response.message());
            return null;
        }
        return response.body();
    } catch (IOException e) {
        Timber.e("IOException %s", e.getMessage());
        return null;
    }
}

/**
 * 指定画像の取得(同期処理)
 */
@WorkerThread
private static Bitmap downloadFile(@NonNull String url) {
    ResponseBody response = getResponse(url);
    if (response == null) {
        return null;
    }

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(response.byteStream(), null, options);
    Timber.d("original image w:%d h:%d", options.outWidth, options.outHeight);

    options.inSampleSize = 1;
    while ((options.outWidth * options.outHeight) / options.inSampleSize > MAX_IMAGE_SIZE * 4) {
        options.inSampleSize *= 2;
    }
    Timber.d("options.inSampleSize: %d", options.inSampleSize);

    options.inJustDecodeBounds = false;
    response = getResponse(url);
    if (response == null) {
        return null;
    }
    Bitmap bitmap = BitmapFactory.decodeStream(response.byteStream(), null, options);
    response.close();
    return bitmap;
}

通信に成功すると、ResponseBodyにHTTPステータスコードやストリーム情報が格納されます。
byteStream()によってInputStreamが取得できるため、通信のやりとり以外は通常のストリームからBitmap生成するやり方になります。

通信周りもresponse.isSuccessful()でステータスコードのチェックが入っていますし、close()処理もおおもとでException周りをキャッチしているので、ネストも少なく非常に見やすいんじゃないかなと思っています。

ただし、これだけの記述では キャッシュ処理がいっさい働いていないので、注意してください。

ちなみにnew OkHttpClient().newCall(request).execute()の部分を

非同期呼び出し.java
new OkHttpClient().newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Request request, IOException e) {
    }

    @Override
    public void onResponse(Response response) throws IOException {
    }
});

と変えることで、通信部分を非同期にできる(はず)ですが、今回の場合は結局Bitmap変換部分もあるので、まとめてAsyncTaskやThreadで処理したほうが見た目にもわかりやすいし、そもそもこのレベルの内容(取得して表示するだけ)であれば、PicassoやGlideを使った方がいいです(本末転倒)。

8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10