Android网络通信框架Volley代码分析(一)
上一篇博文http://www.cnblogs.com/code404/p/3494283.html初步介绍了Volley框架库的相关功能,今天我们就来继续分析框架中的核心类
一. Volley
Volley有2个构造函数
//构造函数1 public static RequestQueue newRequestQueue(Context context) { //直接调用的另外一个构造函数 return newRequestQueue(context, null); }
//构造函数2 public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
....... //以上为省略代码 Network network = new BasicNetwork(stack); RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network); queue.start();
}
构造函数2中的HttpStack是个接口类,提供了一个http请求的方法:
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError;
通过以上代码可以看出Volley的静态方法new一个请求队列,再调用请求队列RequestQueue的start()方法。
然后,得到一个RequestQueue请求队列时,就添加一个请求Request,Volley提供有三种请求的封装,一个是StringRequest,一个事ImageRequest,还有一个是JsonRequest。
最后,调用RequestQueue的start()方法就可以开始一条网络请求了。
二. RequestQueue
所以,这里一个最核心的就是RequestQueue这个请求队列了
RequestQueue这个类提供了3个构造函数(缓存和网络线程构造):
//构造函数1 public RequestQueue(Cache cache, Network network, int threadPoolSize, ResponseDelivery delivery) { } //构造函数2 public RequestQueue(Cache cache, Network network, int threadPoolSize) { //调用函数1 this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper()))); } //构造函数3 public RequestQueue(Cache cache, Network network) { //调用函数2 this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE); }
RequestQueue的成员方法主要有下面几个: public void start();//请求队列开始进行调度 public void stop();//队列退出调度 public Request add(Request request);//添加一个请求,通过调用start()来执行 void finish(Request request);//这个方法应该是释放请求资源的方法 public void cancelAll();//取消当前的请求
三. NetworkDispatcher
在RequestQueue的start()方法中有如下代码:
for (int i = 0; i < mDispatchers.length; i++) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery); mDispatchers[i] = networkDispatcher; networkDispatcher.start(); }
NetworkDispatcher就是网络调度的核心,这是一个继承Thread的类
//构造函数 public NetworkDispatcher(BlockingQueue<Request> queue,Network network, Cache cache,ResponseDelivery delivery)
一个Request的队列,Network ,Cache ,ResponseDelivery
它的run()方法就是循环的在请求队列取出一个Request,让Network 去执行一次请求再通过ResponseDelivery 进行解析.
四. Network
NetWork是一个处理请求的接口类,它只提供一个方法:
public NetworkResponse performRequest(Request<?> request) throws VolleyError;
五. Request
//构造函数 public Request(int method, String url, Response.ErrorListener listener) { mMethod = method; mUrl = url; mErrorListener = listener; setRetryPolicy(new DefaultRetryPolicy()); mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode(); }
上面提到了Request请求封装,是Request的子类
1.StringRequest主要是String类型的返回结果
2.JsonRequest有JsonObjectRequest和JsonArrayRequest两个子类,通过parseNetworkResponse(NetworkResponse response)来处理JsonObject和JsonArray两个不同结果
3.ImageRequest主要是做一些图片的处理
//构造函数 public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight, Config decodeConfig, Response.ErrorListener errorListener) { super(Method.GET, url, errorListener); setRetryPolicy( new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT)); mListener = listener; mDecodeConfig = decodeConfig; mMaxWidth = maxWidth; mMaxHeight = maxHeight; }
六. Response
Request中有个解析NetWorkResponse的方法
abstract protected Response<T> parseNetworkResponse(NetworkResponse response)
然后调用Response.Listener<T>的接口返回String,Json或bitmap
Response有两个接口,一个是Listener回调期望内容的接口和一个ErrorListener接口。
/** Callback interface for delivering parsed responses. */ public interface Listener<T> { /** Called when a response is received. */ public void onResponse(T response); }
onResponse()把想要的json或者string,bitmap数据传回来
综合上面的逻辑,我们再来看看一次完整的代码请求:
mQueue = Volley.newRequestQueue(getApplicationContext()); //StringRequest四个构造参数分别是Request类型,url,网络请求响应监听器,错误监听器 mQueue.add(new StringRequest(Method.GET, "http://www.google.com/", new Listener<String>(){ @Override public void onResponse(String arg0) { // TODO Auto-generated method stub Log.e("onResponse", arg0); } }, new ErrorListener(){ @Override public void onErrorResponse(VolleyError arg0) { // TODO Auto-generated method stub Log.e("onErrorResponse", arg0.toString()); } })); mQueue.start();