Volley 异步网络请求分析

泡在网上的日子 / 文 发表于2015-07-20 12:51 第次阅读 Volley

Volley下载

Google I/O 2013 大会上发布的 Android 异步网络请求框架和图片加载框架。
试用场景:适合数据量小,通信频繁的网络操作。

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

Volley架构

Volley Architect

Volley Architect


如上官方给出的Volley架构图,蓝色为主线程,绿色为缓存线程,橙色是网络线程。

总的来说,就是一个请求队列和三种线程,UI线程(1个),Cache线程(1个)和Network线程(默认是4个)。

  • UI线程负责添加请求任务,执行任务结果;

  • Cache线程负责检查缓存,命中后直接将任务结果分发到主线程;

  • Network线程由多个任务线程(NetworkDispatcher)组成的,相当于一个大小为size的线程池,这些线程会同时启动,并持续的从任务队列中获取待执行的任务,任务执行完后会将结果分发到UI线程。

先简介一下三个类的作用:

  • Volley.java:Volley对外暴露的主类,通过 newRequestQueue(…) 函数新建并启动一个请求队列RequestQueue。

  • Request:请求的抽象类。StringRequest、JsonRequest、ImageRequest 都是它的子类,表示某种类型的请求。可扩展性强。

  • RequestQueue.java:请求队列,里面包含一个CacheDispatcher(用于处理走缓存请求的调度线程)、NetworkDispatcher数组(用于处理走网络请求的调度线程),一个ResponseDelivery(返回结果分发接口),通过 start() 函数启动时会启动CacheDispatcher和NetworkDispatchers。

然后看创建请求队列方法内的代码:

public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
    ...
    Network network = new BasicNetwork(stack);
    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
    queue.start();
    return queue;
}

看到这里,需要了解三个类的作用:

  • HttpStack.java:处理HTTP请求,返回请求结果。目前Volley中有基于 HttpURLConnection 的 HurlStack 和 基于 Apache HttpClient 的HttpClientStack。

  • Network.java:调用HttpStack处理请求,并将结果转换为可被ResponseDelivery处理的NetworkResponse。

  • Cache.java:缓存请求结果,Volley默认使用的是基于sdcard缓存的DiskBasedCache。NetworkDispatcher得到请求结果后判断是否需要存储在 Cache,CacheDispatcher会从 Cache 中取缓存结果。

创建Network需要HttpStatck,如果newRequestQueue传入的stack为null,API Level >= 9,采用基于 HttpURLConnection 的 HurlStack;小于 9,采用基于 HttpClient 的 HttpClientStack。

if (stack == null) {
    if (Build.VERSION.SDK_INT >= 9) {
        stack = new HurlStack();
    } else {
        // Prior to Gingerbread, HttpUrlConnection was unreliable.
        // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
        stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
    }
}

处理HTTP请求的HttpStatck也可以自定义,比如使用OKHTTP,具体可以参见我的另一篇文章使用OKHttp处理Volley的底层HTTP请求

接下来启动所需的所有线程:

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();
    }
}
  • CacheDispatcher.java:继承自Thread,用于调度处理「缓存请求」。启动后会不断从缓存请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理。当结果未缓存过、缓存失效或缓存需要刷新的情况下,该请求都需要重新进入NetworkDispatcher去调度处理。

  • NetworkDispatcher.java:继承自Thread,用于调度处理「网络请求」。启动后会不断从网络请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理,并判断结果是否要进行缓存。

  • ResponseDelivery.java:分发结果的interface,postResponse以及postError。

接下来再回头看一下Volley的架构图。

  • 第一步:把请求加入缓存队列

  • 第二步:「缓存调度线程」CacheDispatcher从缓存队列中取出一个请求,如果缓存命中,就读取缓存响应并解析,然后将结果返回到主线程

  • 第三步:缓存未命中,请求被加入网络请求队列,「网络调度线程」NetworkDispatcher轮询取出请求,HTTP请求传输,解析响应,写入缓存,然后将结果返回到主线程


收藏 赞 (2) 踩 (0)
上一篇:使用OKHttp处理Volley的底层HTTP请求
原文: http://willyan.me/2013/06/01/volley-okhttp/ 1) 导入 Volley (目前没有官方的jar包,需要自己下载源码编译); gitclonehttps://android.googlesource.com/platform/frameworks/volley 2) 导入 OkHttp , okhttp-urlconnection 3) 创建OkHttpStack
下一篇:使用Android Support Annotations优化你的代码
@author ASCE1885的 简书 原文链接 如果你还没有听说过Android Support Annotations 函数库,你将错过一个整洁的新软件包,它有助于你捕获程序中的bugs。该函数库包含了许多的Java注解,用于帮助Android Studio检测代码中可能存在的错误,并报告给开发者。注