Volleyの基本的な使い方。
Gsonを併用した場合の実装について記載
概要
非常に簡単な説明
-
Request
Volleyにおけるネットワーク通信処理(要求)そのもの。
接続先URL、ヘッダ情報、BODYパラメータやリトライポリシー等の通信に関わる情報を実装する。
またレスポンスに対する最初の振る舞いも実装する。 -
RequestQueue
渡されたRequestを順番に実行していくクラス。
シングルインスタンスで扱うべきとされている。 -
ImageLoader
設定したURLを元にリクエストを生成し、レスポンスがあれば指定のImageViewへ自動的に
画像をセットしてくれる。
シングルインスタンスで扱うべきとされている。 -
Gson
Google製Json解析ライブラリ。
実装方法
Gsonを使ったJson解析
VolleyとGsonをよく一緒に使うので、Gsonの使い方を簡単に説明。
例えば以下の様なJsonデータがあると
{
"string_data":"あいうえお",
"integer_data":10,
"array_data":[
{
"data1":"item1",
"data2":20
},
{
"data1":"item2",
"data2":21
},
{
"data1":"item3",
"data2":22
}
]
}
以下の様なオブジェクトを用意してやって
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
基本的な実装
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
基本的な実装
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
基本的な実装
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;
}
}
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」が入る