LoginSignup
29
31

More than 5 years have passed since last update.

【Android】Gson & Volleyの基本的な実装

Last updated at Posted at 2015-07-29

Volleyの基本的な使い方。

Gsonを併用した場合の実装について記載

概要

非常に簡単な説明

  • Request
    Volleyにおけるネットワーク通信処理(要求)そのもの。
    接続先URL、ヘッダ情報、BODYパラメータやリトライポリシー等の通信に関わる情報を実装する。
    またレスポンスに対する最初の振る舞いも実装する。

  • RequestQueue
    渡されたRequestを順番に実行していくクラス。
    シングルインスタンスで扱うべきとされている。

  • ImageLoader
    設定したURLを元にリクエストを生成し、レスポンスがあれば指定のImageViewへ自動的に
    画像をセットしてくれる。
    シングルインスタンスで扱うべきとされている。

  • Gson
    Google製Json解析ライブラリ。

実装方法

Gsonを使ったJson解析

VolleyとGsonをよく一緒に使うので、Gsonの使い方を簡単に説明。
例えば以下の様なJsonデータがあると

Json
{
  "string_data":"あいうえお",

  "integer_data":10,

  "array_data":[
    {
      "data1":"item1",
      "data2":20
    },

    {
      "data1":"item2",
      "data2":21
    },

    {
      "data1":"item3",
      "data2":22
    }
  ]
}

以下の様なオブジェクトを用意してやって

HogeType
public class HogeType {

    public String string_data;
    public Integer integer_data;
    public ArrayList<HogeArrayType> array_data;

    public class HogeArrayType {
        public String data1;
        public Integer data2;
    }

}

以下の様にパースしてやると

パース処理
String json = /* 文字列化したjsonデータとか */
Gson gson = new Gson();
HogeType type = gson.fromJson(json, HogeType.class);

同じ型、名前のフィールドに勝手にデータを投入してくれる
※名前が一致しても型が異なるとExceptionを吐くので注意しよう

Request

基本的な実装

HogeRequest
public class HogeRequest extends Request<HogeType> {
    private final Gson gson = new Gson();
    private final Class<HogeType> clazz;
    private final HogeRequestResponseListener listener;
    private HashMap<String, String> params = new HashMap<>();

    /**
     * 独自データ型のレスポンスリスナーを実装
     */
    public interface HogeRequestResponseListener {
        void onResponse(HogeType response);
    }

    /**
     * リクエストのインスタンス取得
     *
     * @param listener      レスポンスリスナー
     * @param errorListener エラーリスナー
     * @return リクエストのインスタンス
     */
    public static HogeRequest get(HogeRequestResponseListener listener,
                                        Response.ErrorListener errorListener) {
        String url = "URL";
        return new HogeRequest(url, listener, errorListener);
    }

    /**
     * コンストラクタ
     *
     * @param url           URL
     * @param listener      正常終了時のネットワークレスポンス
     * @param errorListener 異常終了時のネットワークレスポンス
     */
    public HogeRequest(String url, HogeRequestResponseListener listener,
                             Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        // 正常時終了時に返却するクラス型セット
        this.clazz = HogeType.class;

        // レスポンスリスナーセット
        this.listener = listener;

        // パラメータセット
        params = new HashMap<>();
        params.put(param1, param2);

    }

    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        return params;
    }

    @Override
    protected void deliverResponse(HogeType response) {
        // 成形したデータを返す
        // リスナーが存在すればレスポンスを返す
        if (this.listener != null) {
            this.listener.onResponse(response);
        } else {
            deliverError(new VolleyError(""));
        }
    }

    @Override
    public void deliverError(VolleyError error) {
        // エラーレスポンス
        super.deliverError(error);
    }

    @Override
    protected Response<HogeType> parseNetworkResponse(NetworkResponse response) {
        // データを成形する
        // 成功:deliverResponse
        // 失敗:deliverError
        try {
            if (response != null && response.data != null && response.headers != null) {
                String json = new String(
                        response.data,
                        HttpHeaderParser.parseCharset(response.headers));
                return Response.success(
                        gson.fromJson(json, clazz),
                        HttpHeaderParser.parseCacheHeaders(response));
            } else {
                return Response.error(new ParseError(new NullPointerException("")));
            }
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            return Response.error(new ParseError(e));
        }
    }
}

RequestQueue

基本的な実装

Application
public class App extends Application {

    private RequestQueue requestQueue;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(this);
        }
        return requestQueue;
    }

}
使用例
App.getRequestQueue().add(HogeRequest.get());

ImageLoader

基本的な実装

Application
public class App extends Application {

    private ImageLoader imageLoader;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    public ImageLoader getImageLoader() {
        if (imageLoader == null) {
            imageLoader = new ImageLoader(getRequestQueue(), new ImageLruCache());
        }
        return imageLoader;
    }

}
ImageLruCache
public class ImageLruCache implements ImageLoader.ImageCache {

    private final LruCache<String, Bitmap> mMemoryCache;

    public ImageLruCache() {
        int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        int cacheSize = maxMemory / 8;

        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getByteCount() / 1024;
            }

            @Override
            protected void entryRemoved(boolean evicted, String key, Bitmap oldVal, Bitmap newVal) {
                super.entryRemoved(evicted, key, oldVal, newVal);
            }

            @Override
            protected Bitmap create(String key) {
                return super.create(key);
            }
        };
    }

    @Override
    public Bitmap getBitmap(String url) {
        return mMemoryCache.get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        mMemoryCache.put(url, bitmap);
    }
}
使用例
    public void setImageLoader(Context context, ImageView imageView, String imageUrl) {
        // 画像
        if (imageView != null && imageUrl != null) {
            try {
                ImageLoader.ImageContainer imageContainer =
                        (ImageLoader.ImageContainer) imageView.getTag();

                if (imageContainer != null) {
                    imageContainer.cancelRequest();
                }

            } catch (ClassCastException ignore) {
            }

            ImageLoader.ImageListener listener = 
                    ImageLoader.getImageListener(imageView, R.drawable.hoge, R.drawable.fuga);
            imageView.setTag(App.get().getImageLoader().get(imageUrl, listener));
        }
    }

Tips(2015/09/09追記)

Gsonパースする時の「null」値について

{
    "int_val":null
}

こういうデータに対してオブジェクトを用意するとき

int int_val;

こうすると自動で「0」が入り

Integer int_val;

こうすると「null」が入る

29
31
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
29
31