首页 > 代码库 > [Android]Volley源码分析(一)
[Android]Volley源码分析(一)
一. 如何使用Volley?
1. 首先定义一个RequestManager类,用来在Android程序启动时对Volley进行初始化。RequestManager为单例类,因为只有在程序启动时调用,所以不需要考虑并发问题。
1 /** 2 * Manager for the queue 3 */ 4 public class RequestManager { 5 6 /** 7 * 请求队列 8 */ 9 private static RequestQueue mRequestQueue;10 11 /**12 * 私有化构造函数13 */14 private RequestManager() {15 // no instances16 } 17 18 /**19 * @param context 应用程序上下文20 */21 public static void init(Context context) {22 mRequestQueue = Volley.newRequestQueue(context);23 }24 25 /**26 * @return27 * 请求队列28 * @throws29 * IllegalStatException if init has not yet been called30 */31 public static RequestQueue getRequestQueue() {32 if (mRequestQueue != null) {33 return mRequestQueue;34 } else {35 throw new IllegalStateException("Not initialized");36 }37 }38 }
2. 为了方便对请求的Body(PUT或POST请求时)及响应体进行解析,我们可以继承Volley的Request类,自定义一个通过Gson来解析请求与响应的Request。
1 /** 2 * Wrapper for Volley requests to facilitate parsing of json responses. 3 */ 4 public class MyGsonRequest<T> extends Request<T>{ 5 6 /** Charset for request. */ 7 private static final String PROTOCOL_CHARSET = "utf-8"; 8 /** Content type for request. */ 9 private static final String PROTOCOL_CONTENT_TYPE =10 String.format("application/json; charset=%s", PROTOCOL_CHARSET);11 /**12 * Gson parser 13 */14 private final Gson mGson;15 /**16 * Class type for the response17 */18 private final Class<T> mResponseClass;19 private final Object mRequestBody;20 21 22 /**23 * Callback for response delivery 24 */25 private final Listener<T> mListener;26 27 /**28 * @param method29 * Request type.. Method.GET etc30 * @param url31 * path for the requests32 * @param requestBody33 * Q type instance as request body, if no request body needed set it to null34 * @param responseClass35 * expected class type for the response. Used by gson for serialization.36 * @param listener37 * handler for the response38 * @param errorListener39 * handler for errors40 */41 public MyGsonRequest(int method42 , String url 43 , Object requestBody44 , Class<T> responseClass45 , Listener<T> listener46 , ErrorListener errorListener) {47 48 super(method, url, errorListener);49 this.mRequestBody = requestBody;50 this.mResponseClass = responseClass;51 this.mListener = listener;52 mGson = new Gson();53 54 }55 56 @Override57 protected Response<T> parseNetworkResponse(NetworkResponse response) {58 try {59 String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));60 return Response.success(mGson.fromJson(json, mResponseClass),61 HttpHeaderParser.parseCacheHeaders(response));62 } catch (UnsupportedEncodingException e) {63 return Response.error(new ParseError(e));64 } catch (JsonSyntaxException e) {65 return Response.error(new ParseError(e));66 }67 }68 69 @Override70 protected void deliverResponse(T response) {71 mListener.onResponse(response);72 }73 74 @Override75 public String getBodyContentType() {76 return PROTOCOL_CONTENT_TYPE;77 }78 79 @Override80 public byte[] getBody() {81 try {82 return mRequestBody == null ? null : mGson.toJson(mRequestBody).getBytes(PROTOCOL_CHARSET);83 } catch (UnsupportedEncodingException uee) { 84 VolleyLog85 .wtf("Unsupported Encoding while trying to get the bytes of %s using %s",86 mGson.toJson(mRequestBody), PROTOCOL_CHARSET); 87 return null;88 }89 }90 }
需要重写Request的以下方法:
1). parseNetworkResponse 通过Gson将服务器返回的Json字符串解析为你想要的对象 mGson.fromJson(json, mResponseClass)
2). deliverResponse 调用你自定义的实现了Response.Listener接口的回调方法onResponse
3). getBodyContentType 获取请求体的内容类型,如json类型,编码为utf-8
4). getBody 获取请求体的字节数组表示。 同样是通过Gson将你的请求体中对象转换为Json字符串来获取字节数组 mGson.toJson(mRequestBody).getBytes(PROTOCOL_CHARSET)
3. 接下来可以针对不同的领域模型定义一些客户端类,比如对用户的一些服务器请求操作可以定义一个UserManager类,实现注册、登录等功能。
public class UserManager { public static UserManager getInstance(){ if(mInstance == null) { mInstance = new UserManager(); } return mInstance; } public void register(Listener<String> listener, ErrorListener errorListener, User user){ Uri.Builder uriBuilder = Uri.parse(USER_BASE_URL).buildUpon(); String uri = uriBuilder.build().toString(); MyGsonRequest<String> request = new MyGsonRequest<String>(Method.POST , uri , user , String.class , listener , errorListener); Log.v(TAG, request.toString()); RequestManager.getRequestQueue().add(request); }}
上述代码实例化了一个request,将这个request加入Volley的请求队列中,由Volley来负责对请求进行调度处理。
3. 然后别忘了在程序的Application类中,对Volley进行初始化
1 public class MainApplication extends Application { 2 @Override 3 public void onCreate() { 4 super.onCreate(); 5 RequestManager.init(this); 6 //其他初始化 7 } 8 ... 9 }10
4. 最后在具体的Activity中,就可以通过如下方式对服务器发起注册请求了。
//比如点击注册按钮,在onClick方法中调用
UserManager.getInstance().register(createLoginSuccessListener(), createLoginErrorListener(), user);
//请求成功返回时调用
private Listener<String> createRegisterSuccessListener() {
return new Listener<String>() {
@Override
public void onResponse(String response) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
Toast.makeText(
RegisterActivity.this,
getString(R.string.msg_register_success),
Toast.LENGTH_SHORT).show();
}
};
}
//请求失败时调用
private Response.ErrorListener createRegisterErrorListener() {
return new Response.ErrorListener() {
@Override
public void one rrorResponse(VolleyError error) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
Toast.makeText(
RegisterActivity.this,
VolleyErrorUtil.getMessage(error, RegisterActivity.this),
Toast.LENGTH_SHORT).show();
}
};
}