Google Volleyフレームワークの説明-第2編

31001 ワード

Volleyが提供する機能
簡単に言えば、以下の主な機能が提供されています.
1、カプセル化された非同期のRESTful要求API;
2、優雅で穏健なリクエストキュー;
3、開発者がカスタムの要求と応答処理メカニズムを実現できるように拡張可能なアーキテクチャ.
4、外部HTTP Clientライブラリを使用できる;
5、キャッシュポリシー;
6、カスタムネットワーク画像ロードビュー(NetworkImageView、ImageLoaderなど);
要求キューの使用
Volleyのすべてのリクエストは1つのキューに配置され、処理されます.ここでは、リクエストキューを作成する方法について説明します.
RequestQueue mRequestQueue = Volley.newRequestQueue(this); // 'this' is Context

理想的には、リクエスト・キューを1つの場所に集約することです.アプリケーション・クラスでリクエスト・キューを初期化することが望ましいです.次のクラスでは、これを行います.
public class ApplicationController extends Application {
 
    
    public static final String TAG = "VolleyPatterns";
 
    
    private RequestQueue mRequestQueue;
 
    
    private static ApplicationController sInstance;
 
    @Override
    public void onCreate() {
        super.onCreate();
 
        // initialize the singleton
        sInstance = this;
    }
 
    
    public static synchronized ApplicationController getInstance() {
        return sInstance;
    }
 
    
    public RequestQueue getRequestQueue() {
        // lazy initialize the request queue, the queue instance will be
        // created when it is accessed for the first time
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
 
        return mRequestQueue;
    }
 
    
    public void addToRequestQueue(Request req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
 
        VolleyLog.d("Adding request to queue: %s", req.getUrl());
 
        getRequestQueue().add(req);
    }
 
    
    public void addToRequestQueue(Request req) {
        // set the default tag if tag is empty
        req.setTag(TAG);
 
        getRequestQueue().add(req);
    }
 
    
    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }

非同期JSON、Stringリクエスト
Volleyでは、非同期HTTPリクエストを行うユーティリティクラスが用意されています.
JsonObjectRequest — To send and receive JSONObject from the Server
JsonArrayRequest — To receive JSON Array from theServer
StringRequest — To retrieve response body asString (ideally if you intend to parse the response byyourself)
JsonObjectRequest
このクラスは、JSONオブジェクトを送信および受信するために使用できます.このクラスのリロード構造関数を使用すると、適切なリクエストメソッド(DELETE、GET、POST、PUT)を設定できます.RESTfulサービスを使用している場合は、このクラスを使用できます.次の例では、GETおよびPOSTリクエストの使用方法を示します.
GETリクエスト:
ffinal String URL = "/volley/resource/12";
// pass second argument as "null" for GET requests
JsonObjectRequest req = new JsonObjectRequest(URL, null,
       new Response.Listener() {
           @Override
           public void onResponse(JSONObject response) {
               try {
                   VolleyLog.v("Response:%n %s", response.toString(4));
               } catch (JSONException e) {
                   e.printStackTrace();
               }
           }
       }, new Response.ErrorListener() {
           @Override
           public void onErrorResponse(VolleyError error) {
               VolleyLog.e("Error: ", error.getMessage());
           }
       });
 
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);

POST要求:
final String URL = "/volley/resource/12";
// Post params to be sent to the server
HashMap params = new HashMap();
params.put("token", "AbCdEfGh123456");
 
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
       new Response.Listener() {
           @Override
           public void onResponse(JSONObject response) {
               try {
                   VolleyLog.v("Response:%n %s", response.toString(4));
               } catch (JSONException e) {
                   e.printStackTrace();
               }
           }
       }, new Response.ErrorListener() {
           @Override
           public void onErrorResponse(VolleyError error) {
               VolleyLog.e("Error: ", error.getMessage());
           }
       });
 
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);

JsonArrayRequest
このクラスはJSON Arrayを受け入れるために使用できます.JSON Objectはサポートされていません.このクラスはHTTPGETのみサポートされています.GETがサポートされているため、URLの後ろに要求パラメータを付けることができます.クラスのコンストラクション関数は要求パラメータをサポートしていません.
final String URL = "/volley/resource/all?count=20";
JsonArrayRequest req = new JsonArrayRequest(URL, new Response.Listener () {
    @Override
    public void onResponse(JSONArray response) {
        try {
            VolleyLog.v("Response:%n %s", response.toString(4));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        VolleyLog.e("Error: ", error.getMessage());
    }
});

StringRequest
このクラスは、サーバからStringを取得するために使用できます.リクエスト応答を自分で解析するには、xmlデータを返すなどのクラスを使用します.また、リロードされたコンストラクション関数を使用してリクエストをカスタマイズすることもできます.
final String URL = "/volley/resource/recent.xml";
StringRequest req = new StringRequest(URL, new Response.Listener() {
    @Override
    public void onResponse(String response) {
        VolleyLog.v("Response:%n %s", response);
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        VolleyLog.e("Error: ", error.getMessage());
    }
});
 
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);

リクエストのキャンセル
Volleyは強力なAPIを提供し、未処理または処理中のリクエストをキャンセルします.リクエストをキャンセルする最も簡単な方法は、リクエストキューcancelAll(tag)を呼び出す方法で、リクエストを追加するときにタグを設定したことを前提としています.これにより、ラベルタグのリクエストを保留できます.
要求にラベルを設定するには、次の手順に従います.
request.setTag("My Tag");

ApplicationControllerを使用して、ラベルを使用したリクエストをキューに追加します.
ApplicationController.getInstance().addToRequestQueue(request, "My Tag");

指定したタグのすべての要求をキャンセルするには、次の手順に従います.
mRequestQueue.cancelAll("My Tag");

再試行に失敗したリクエスト、カスタムリクエストタイムアウト
Volleyには要求タイムアウト時間を設定する方法が指定されていません.RetryPolicyを設定して実装を変更できます.DefaultRetryPolicyクラスにはinitialTimeoutパラメータがあり、タイムアウト時間を設定できます.タイムアウト後に再要求しないように最大再試行回数を1にします.
Setting Request Timeout
request.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 1,1.0f));
要求ヘッダの設定(HTTP headers)      タイムアウトのために失敗した後に再要求したい場合は、上記のコードを使用して再試行回数を増やすことを指定できます.最後のパラメータに注意してください.これにより、RESTfulサーバからデータを要求するためにインデックスバックオフを実現するためにバックオフ乗数を指定できます.
HTTPリクエストに追加のヘッダ情報を追加する必要がある場合があります.一般的な例として、「Authorization」をHTTPリクエストのヘッダ情報に追加することがあります.Volleyリクエストクラスは、HTTPのヘッダ情報をカスタマイズできるgetHeers()の方法を提供します.
ヘッダ情報を追加:
JsonObjectRequest req = new JsonObjectRequest(URL, 
         new JSONObject(params),
           new Response.Listener() {
             @Override
               public void onResponse(JSONObject response) {
                   // handle response 
           } 
         }, new Response.ErrorListener() {
              @Override
               public void onErrorResponse(VolleyError error) {
                   // handle error 
                  }
           }) {
             @Override 
                public Map getHeaders() throws AuthFailureError { 
                           HashMap headers = new HashMap();
           headers.put("CUSTOM_HEADER", "Yahoo");                                     headers.put("ANOTHER_CUSTOM_HEADER", "Google"); 
                            return headers; 
                 }
           };

Cookiesの使用
Volleyにはcookiesを設定する直接的なAPIはありません.Volleyの設計理念は、RESTfulHTTPリクエストを実現するために清潔で簡潔なAPIを提供することであり、cookiesの設定を提供しないのは合理的です.
次は、getRequestQueue()メソッドを変更したアプリケーションコントローラクラスです.クッキーの設定メソッドが含まれていますが、これらの変更はまだ粗いです.
private DefaultHttpClient mHttpClient;
public RequestQueue getRequestQueue() {
    // lazy initialize the request queue, the queue instance will be
    // created when it is accessed for the first time
    if (mRequestQueue == null) {
        // Create an instance of the Http client. 
        // We need this in order to access the cookie store
        mHttpClient = new DefaultHttpClient();
        // create the request queue
        mRequestQueue = Volley.newRequestQueue(this, new HttpClientStack(mHttpClient));
    }
    return mRequestQueue;
}
 
public void setCookie() {
    CookieStore cs = mHttpClient.getCookieStore();
    // create a cookie
    cs.addCookie(new BasicClientCookie2("cookie", "spooky"));
}
 
 
// add the cookie before adding the request to the queue
setCookie();
 
// add the request to the queue
mRequestQueue.add(request);

エラー処理
前述のコードで説明したように、リクエストを作成するときに、onErrorResponseのエラーリスニングを追加する必要があります.リクエストに異常が発生した場合、VolleyErrorインスタンスが返されます.
以下はVolleyの例外のリストです.
AuthFailureError:HTTPの認証をしている場合、このエラーが発生する可能性があります.
NetworkError:Socketがシャットダウンし、サーバがダウンし、DNSエラーが発生します.
NoConnectionError:NetworkErrorと同様に、クライアントにはネットワーク接続がありません.
ParseError:JsonObjectRequestまたはJsonArrayRequestを使用する場合、受信したJSONが奇形の場合、異常が発生します.
SERVERERROR:サーバの応答のエラー、最も可能性のある4 xxまたは5 xx HTTPステータスコード.
TimeoutError:Socketがタイムアウトし、サーバーが多忙またはネットワーク遅延するとこの異常が発生します.デフォルトでは、Volleyのタイムアウト時間は2.5秒です.このエラーが発生した場合はRetryPolicyを使用します.
簡単なHelpクラスを使用して、これらの例外プロンプトに対応する情報を提示できます.
public class VolleyErrorHelper {
     
  public static String getMessage(Object error, Context context) {
      if (error instanceof TimeoutError) {
          return context.getResources().getString(R.string.generic_server_down);
      }
      else if (isServerProblem(error)) {
          return handleServerError(error, context);
      }
      else if (isNetworkProblem(error)) {
          return context.getResources().getString(R.string.no_internet);
      }
      return context.getResources().getString(R.string.generic_error);
  }
  
  
  private static boolean isNetworkProblem(Object error) {
      return (error instanceof NetworkError) || (error instanceof NoConnectionError);
  }
  
  private static boolean isServerProblem(Object error) {
      return (error instanceof ServerError) || (error instanceof AuthFailureError);
  }
  
  private static String handleServerError(Object err, Context context) {
      VolleyError error = (VolleyError) err;
  
      NetworkResponse response = error.networkResponse;
  
      if (response != null) {
          switch (response.statusCode) {
            case 404:
            case 422:
            case 401:
                try {
                    // server might return error like this { "error": "Some error occured" }
                    // Use "Gson" to parse the result
                    HashMap result = new Gson().fromJson(new String(response.data),
                            new TypeToken>() {
                            }.getType());

                    if (result != null && result.containsKey("error")) {
                        return result.get("error");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
                // invalid request
                return error.getMessage();

            default:
                return context.getResources().getString(R.string.generic_server_down);
            }
      }
        return context.getResources().getString(R.string.generic_error);
  }
}

まとめ:
Volleyは非常に良いライブラリであり、使用してみると、ネットワークリクエストを簡素化し、より多くのメリットをもたらすことができます.