Volley网络框架
由来
volley 是 Goole I/O 2013上发布的网络通信库,使网络通信更快、更简单、更健壮。 数据不大但通信频繁
Volley //内部封装了HttpURLConnection和HttpClient
使用场景
网络通信更快、更简单、更健壮。 适用于数据不大但通信频繁的场景,不适合大文件下载。
注意事项:一般整个App只使用一个请求队列RequestQueue//定义一个类继承Application进行初始化,注意清单加name
功能
Json,图像等异步下载
网络请求的排序(scheduling)
网络请求的优先级处理
缓存
多级别取消请求
和 Activity 的生命周期联动(Activity 结束时同时取消所有网络请求)
更具体请参考http://www.jianshu.com/p/ec3dc92df581
Build.VERSION.SDK_INT获取手机版本号
谷歌在高版本当中已经去掉了httpClient,所以这里必须做版本号的判断。
版本号大于等于9就使得HttpStack对象的实例为HurlStack(使用了HttpURLConnection),如果小于9则实例为HttpClientStack(使用了HttpClient)。
Volley的简单使用
注意事项:一般整个App只使用一个请求队列RequestQueue//定义一个类继承Application进行初始化,注意清单加name
代码使用
//[1]请求队列的对象
RequestQueue mQueue = Volley.newRequestQueue(context);
//[2]创建JsonObjectRequest对象(抽象类,多态)用来请求 JSON 数据
//JsonObjectRequest,StringRequset等
JsonObjectRequest request = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
//参数2请求体requestBody,用Json数据请求服务器
@Override
public void onResponse(JSONObject jsonObject) {
// TODO
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
// TODO
}
});
//[3]请求对象加入 mQueue 的队列中
mQueue.add(request);
//Volley图片控件NetworkImageView
mNetworkImageView.setImageUrl(url,imageLoader);//参数2:缓存对象
Volley源码分析
[1]创建RequestQueue对象
RequestQueue queue = Volley.newRequestQueue(context);
调用newRequestQueue(context,httpStack)
RequestQueue newRequestQueue(context,httpStack){
发起网络请求.//HttpStack//NetWork//线程池,4个线程NetWorkDispatcher
初始化磁盘缓存:创建磁盘缓存对象DiskBasedcache
分发器Delivery分发,//TODO,绑定Handler,绑定主线程Looper//Looper.getMainLooper()作用:线程切换
RequestQueue的start(){
开启1线程mCacheDispatcher.start();//开启线程自动run()//mCacheDispatcher.run()
开启4线程 networkDispatcher.start();//开启线程自动run()//mCacheDispatcher.run().run()
}
return queue;
}
//可以优化的地方(Volley的缺点),线程池(4个NetworkDispatcher)没有管理,只是简单的一个数组,一旦线程池挂了,就访问不了网络了.
[2]请求队列添加请求//queue.add(request)
不用排队mCurrentRequests: 添加到当前请求mCurrentRequests.add(request);
要排队mWaitingRequests: 添加到请求队列mCacheQueue.add(request)
没有请求:请求到网络队列mNetworkQueue.add(request);
[3]CacheDispatcher.start()线程开启触发CacheDispatcher的run()
设置线程优先级Process.setThreadPriority
while(true){
拿到请求mCacheQueue.take();
请求判断是否可用:
request.isCanceled()
获取缓存:
Cache.Entry entry = mCache.get(request.getCacheKey());
缓存判断:
有缓存:
//读取数据:Cache.Entry
//解析和返回结果response: request.parseNetworkResponse
没有缓存or过期: 无缓存entry == null//过期entry.isExpired()
mNetworkQueue.put(request);
有缓存但是否需要刷新: //if(!entry.refreshNeeded())
否:通过分发器分发mDelivery.postResponse(request, response);
是:通过分发并重新请求
mDelivery.postResponse(request, response, new Runnable() {
@Override
public void run() {
mNetworkQueue.put(request);
}
}
}
[4]networkDispatcher.start()线程开启触发NetWorkDispatcher的run()
设置线程优先级Process.setThreadPriority()
while (true) {
拿到请求mQueue.take();
执行网络请求NetworkResponse networkResponse = mNetwork.performRequest(request);
解析和返回结果response: request.parseNetworkResponse(networkResponse);
当网络可用并且有数据就缓存
if (request.shouldCache() && response.cacheEntry != null) {
mCache.put(request.getCacheKey(), response.cacheEntry);
request.addMarker("network-cache-written");
}
通过分发器分发: mDelivery.postResponse(request, response);
}