Android.Volley的解读:初始接触volley
public RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
一切都从这句代码开始。。。
跟着newRequestQueue(Context)到Volley类中
public class Volley { ... public static RequestQueue newRequestQueue(Context context) { return newRequestQueue(context, null); } }
1 public static RequestQueue newRequestQueue(Context context, HttpStack stack) { 2 File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR); 3 4 String userAgent = "volley/0"; 5 try { 6 String packageName = context.getPackageName(); 7 PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); 8 userAgent = packageName + "/" + info.versionCode; 9 } catch (NameNotFoundException e) { 10 } 11 12 if (stack == null) {//你开始传null,所以走这里 13 if (Build.VERSION.SDK_INT >= 9) { 14 stack = new HurlStack();//SDK如果大于等于9,也就是Android 2.3以后,因为引进了HttpUrlConnection 15 } else {//如果小于9,则是用HttpClient来实现 16 // Prior to Gingerbread, HttpUrlConnection was unreliable. 17 // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html 18 stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); 19 } 20 } 21 22 Network network = new BasicNetwork(stack); 23 //创建一个Network,参数stack是用来网络通信 24 RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network); 25 queue.start(); 26 27 return queue; 28 }
接下来就是RequestQueue了,F2跟进去
public RequestQueue(Cache cache, Network network) { this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE); } ... public RequestQueue(Cache cache, Network network, int threadPoolSize) { this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper()))); } ... public RequestQueue(Cache cache, Network network, int threadPoolSize, ResponseDelivery delivery) { mCache = cache; //private final Cache mCache用于缓存 mNetwork = network; //private final Network mNetwork用于连接网络 mDispatchers = new NetworkDispatcher[threadPoolSize]; /NetworkDispatcher继承thread,网络派发线程池 mDelivery = delivery; // 传递Response的实现 }
以上四个参数中,前两个是传入参数,后两个参数,threadPoolSize线程池数,默认为4,剩下最后一个,进入ExecutorDelivery(new Handler(Looper.getMainLooper()))
public ExecutorDelivery(final Handler handler) { // Make an Executor that just wraps the handler. mResponsePoster = new Executor() { @Override public void execute(Runnable command) { handler.post(command); } }; }
可以看到Handler将Response传回主线程,进行更新。
自此,代码RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network),已经执行完,下一句就是queue.start()了
看看start的代码,如下
/** * Starts the dispatchers in this queue. */ public void start() { stop(); // Make sure any currently running dispatchers are stopped. // Create the cache dispatcher and start it. mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery); mCacheDispatcher.start(); // Create network dispatchers (and corresponding threads) up to the pool size. for (int i = 0; i < mDispatchers.length; i++) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery); mDispatchers[i] = networkDispatcher; networkDispatcher.start(); } } /** * Stops the cache and network dispatchers. */ public void stop() { if (mCacheDispatcher != null) { mCacheDispatcher.quit(); } for (int i = 0; i < mDispatchers.length; i++) { if (mDispatchers[i] != null) { mDispatchers[i].quit(); } } }
其中可以看到,start函数先调用stop退出mCacheDispatcher和mDispatchers的所有工作线程,确保当前正在运行的派发线程都停止以后,再重新创建并启动派发线程。
mDispatchers很好理解,就是RequestQueue初始化的网络派发线程池,那mCacheDispatcher是什么呢,字面意思就是缓存调度者(派发器)
看他构造函数中的四个参数,后两个mCache和mDelivery就是从第一句代码传进来的参数,比较好理解,剩下前面两个参数:mCacheQueue和mNetworkQueue
在RequestQueue.java中可以找到它两的定义,如下:
/** The cache triage queue. */ private final PriorityBlockingQueue<Request<?>> mCacheQueue = new PriorityBlockingQueue<Request<?>>(); /** The queue of requests that are actually going out to the network. */ private final PriorityBlockingQueue<Request<?>> mNetworkQueue = new PriorityBlockingQueue<Request<?>>();
PriorityBlockingQueue是java并发包java.util.concurrent提供的,使用PriorityBlockingQueue可以进行任务按优先级同步执行。看看泛型定义成Request可以联想到这两个队列应该是用来存储缓存请求和网络请求的。
自此volley的第一句代码已经执行完毕,返回一个RequestQueue了,我来自己总结一下第一句代码做了些什么:
1.第一步是从传入参数context定义好缓存目录cacheDir,包名版本号userAgent,HttpStack协议栈;利用协议栈创建network网络接口;利用缓存目录创建硬盘缓存cache
2.把network和cache传入RequestQueue创建请求队列,其中经过2步构造函数的重载跳转,新增加了网络派发线程池mDispatchers和应答传递者mDelivery,四个参数实现完成了RequestQueue的初始化工作。
3.requestqueue初始化完成后,调用start启动请求队列正式工作。其中start先是把requestqueue中的所有mCacheDispatcher和mDispatchers的工作线程退出,并重新加载。两者的创建都需要用到了RequestQueue内部私有成员PriorityBlockingQueue<Request<?>> mCacheQueue 和 PriorityBlockingQueue<Request<?>> mNetworkQueue。
自于mCacheQueue和mNetworkQueue实际的工作原理,就得分开记录了~
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。