Google Volley框架源码走读

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!

开源项目链接

Volley自定义 Android Developer文档

Volley主页:https://android.googlesource.com/platform/frameworks/volley

Volley仓库:git clone https://android.googlesource.com/platform/frameworks/volley

Volley GitHub Demo:在GitHub主页搜索Volley会有很多,不过建议阅读Android Developer文档。

背景知识

在Volley使用基础那一篇最后一个知识点说到了Volley的请求架构,这里再搬过来说说。

在Android Developer上看到的这幅图:

RequestQueue会维护一个缓存调度线程(cache线程)和一个网络调度线程池(net线程),当一个Request被加到队列中的时候,cache线程会把这个请求进行筛选:如果这个请求的内容可以在缓存中找到,cache线程会亲自解析相应内容,并分发到主线程(UI)。如果缓存中没有,这个request就会被加入到另一个NetworkQueue,所有真正准备进行网络通信的request都在这里,,第一个可用的net线程会从NetworkQueue中拿出一个request扔向服务器。当响应数据到的时候,这个net线程会解析原始响应数据,写入缓存,并把解析后的结果返回给主线程。

硬着头皮开始吧

直接这么看好空洞,所以直接把clone的工程导入IDE边看代码边看这个图吧。

还是按照前边的顺序分析吧,使用Volley的第一步首先是通过Volley.newRequestQueue(context)得到RequestQueue队列,那么先看下toolbox下的Volley.java中的这个方法吧。

/** * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it. * * @param context A {@link Context} to use for creating the cache dir. * @return A started {@link RequestQueue} instance. */public static RequestQueue newRequestQueue(Context context) {return newRequestQueue(context, null);}

先看如上注释所示,创建一个默认的worker pool,并且调运RequestQueue的start方法。在这个方法里又调运了该类的另一个连个参数的重载方法,如下所示。

/** * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it. * * @param context A {@link Context} to use for creating the cache dir. * @param stack An {@link HttpStack} to use for the network, or null for default. * @return A started {@link RequestQueue} instance. */public static RequestQueue newRequestQueue(Context context, HttpStack stack) {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 = packageName + “http://blog.csdn.net/” + info.versionCode;} catch (PackageManager.NameNotFoundException e) {}if (stack == null) {if (Build.VERSION.SDK_INT >= 9) {stack = new HurlStack();} else {// Prior to Gingerbread, HttpUrlConnection was unreliable.// See: stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));}}Network network = new BasicNetwork(stack);RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);queue.start();return queue;}

如上所示,该方法有两个参数,第一个Context是为了拿到当前App的Activity的一些信息,第二个参数在默认的RequestQueue newRequestQueue(Context context)方法中传递为null,也就是说在这段代码中的if (stack == null)会被执行。在这个if中对版本号进行了判断,如果版本号大于等于9就使得HttpStack对象的实例为HurlStack,如果小于9则实例为HttpClientStack。至于这里为何进行版本号判断,实际代码中的(Click Me To See)注释已经说明了。实际上HurlStack类也在toolbox中,他实现了toolbox的HttpStack接口中的HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)方法,其实现过程使用的是HttpURLConnection。而HttpClientStack也在toolbox中,他也实现了toolbox的HttpStack接口的HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)方法,不过其实现过程使用的是HttpClient而已。

其中的userAgent就是App的包名加版本号而已,传入new HttpClientStack(AndroidHttpClient.newInstance(userAgent));作为name TAG使用。

如上HttpStack创建完成之后创建了Network实例。BasicNetwork是Network接口的实现,他们都在toolbox中,BasicNetwork实现了public NetworkResponse performRequest(Request<?> request)方法,其作用是根据传入的HttpStack对象来处理网络请求。紧接着new出一个RequestQueue对象,并调用它的start()方法进行启动,然后将RequestQueue返回。RequestQueue是根目录下的一个类,其作用是一个请求调度队列调度程序的线程池。这样newRequestQueue()的方法就执行结束了。

现在再来看下根目录下RequestQueue队列的start方法,如下所示:

/** * Starts the dispatchers in this queue. */() {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();}}年岁有加,并非垂老,理想丢弃,方堕暮年。

Google Volley框架源码走读

相关文章:

你感兴趣的文章:

标签云: