@[Volley, 入口, 框架]
声明:转载请注明出处,知识有限,如有错误,请多多交流指正!
原理:主要是将请求添加到RequestQueue,再通过CacheDispatcher(缓存调度器)和NetworkDispatcher(网络请求调度器)获取分发,通过是否缓存来调用Cache和网络请求,也就是从缓存中或者服务器中获取数据,获取数据之后通过ResponseDelivery去做结果分发及回调处理
在主线程中发起请求,如果有缓存,则直接读取缓存,响应结果;如果没有缓存则进行网络请求,响应结果;Volley在不同的线程上异步执行所有请求而避免了阻塞主线程.
其中:
主线程发起请求——主线程
缓存和网络线程处理请求获取数据——子线程
响应数据——主线程
响应数据在主线程这样做的好处,就是可以在请求回调中可以直接操作UI
Volley.java:入口类
public static RequestQueue newRequestQueue(Context context)
public static RequestQueue newRequestQueue(Context context, HttpStack stack)
public static RequestQueue newRequestQueue(Context context, int maxDiskCacheBytes)
public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes)
主要通过newRequestQueue这个方法创建请求队列,主要调用一下代码:
public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes) {
// context.getCacheDir() : /data/data/应用包名/cache
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
String userAgent = "volley/0";
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
//userAgent : com.android.volley.test/1
userAgent = packageName + "/" + info.versionCode;
} catch (NameNotFoundException e) {
}
//创建网络请求
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
//HttpURLConnection
stack = new HurlStack();
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
//HttpClient
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
Network network = new BasicNetwork(stack);
//创建请求队列
RequestQueue queue;
if (maxDiskCacheBytes <= -1) {
// No maximum size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
} else {
// Disk cache size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);
}
queue.start();
return queue;
}
其中
- File cacheDir : 缓存目录
- HurlStack:封装的是HttpURLConnection请求
- HttpClientStack:封装的是HttpClient请求
- RequestQueue:请求队列
- DiskBasedCache:磁盘缓存
(1)主要步骤:
- 创建缓存文件和userAgent
- 创建网络请求
- 将缓存、网络请求关联到请求队列
- 启动请求队列
(2)什么是userAgent ?
可以查看W3C解释说明:HTML DOM userAgent 属性
userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值——摘自w3school
(3) 为什么在Android2.3(api level=9)网络请求方式不一样?
- 主要是由于在Android2.2之前HttpURLConnection存在一些bug,调用 close() 函数会影响连接池,导致连接复用失效,所以在 Froyo 之前使用 HttpURLConnection 需要关闭 keepAlive。
- 在 Android2.3 HttpURLConnection 默认开启了 gzip 压缩,提高了 HTTPS 的性能,Ice Cream Sandwich(4.0) HttpURLConnection 支持了请求结果缓存。
- 两种请求对比,可以参考Android HttpURLConnection及HttpClient选择
扩展:也就是Android 2.3后续版本对HttpURLConnection支持比较好,于此同时在Android5.1已经去除弃用HttpClient,所以不建议使用,其实在Android5.1已经添加了OkHttp请求,只是接口不可见,相信后期Google也会开放OkHttp接口