Android Volley的优缺点及源码分析

为什么volley不适合post大量数据,以及为什么不适合上传下载大量文件?

因为,volley中为了提高请求处理的速度,采用了ByteArrayPool进行内存中的数据存储的,如果下载大量的数据,这个存储空间就会溢出,所以不适合大量的数据。但是由于它的这个存储空间是内存中分配的,当存储的时候会先从ByteArrayPool中取出一块已经分配的内存区域, 不必每次存数据都要进行内存分配,而是先查找缓冲池中有无适合的内存区域,如果有,直接拿来用,从而减少内存分配的次数,所以他比较适合大量的数据量少的网络数据交互情况。还有一个原因是volley 的线程池是基于数组实现的,即newFixedThreadPool(4)核心线程数不超过4个,也不会自动扩展,一旦大数据上传或者下载长时间占用了线程资源,后续所有的请求都会被阻塞。最后,Volley是不适合上次和下载大文件,但不代表不能处理大文件。BasicNetwork是volley处理返回response的默认实现,它是把server返回的流全部导入内存,ByteArrayPool只是一个小于4k的内存缓存池,在BasicNetwork里实现。上传和BasicNetwork应该没有多大关系,volley也是可以上传大数据的,volley也是可以下载大数据的,只是你不要使用BasicNetwork就行了。

 

源码分析

其实,Volley的官方文档中本身就附有了一张Volley的工作流程图,如下图所示。

多数朋友突然看到一张这样的图,应该会和我一样,感觉一头雾水吧?没错,目前我们对Volley背后的工作原理还没有一个概念性的理解,直接就来看这张图自然会有些吃力。不过没关系,下面我们就去分析一下Volley的源码,之后再重新来看这张图就会好理解多了。

 

说起分析源码,那么应该从哪儿开始看起呢?这就要回顾一下Volley的用法了,使用Volley的第一步,首先要调用Volley.newRequestQueue(context)方法来获取一个RequestQueue对象,代码如下所示:

public static RequestQueue newRequestQueue(Context context) {  
    return newRequestQueue(context, null);  
}  

这个方法仅仅只有一行代码,只是调用了newRequestQueue()的方法重载,并给第二个参数传入null。那我们看下带有两个参数的newRequestQueue()方法中的代码,如下所示:

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 + "/" + info.versionCode;  
    } catch (NameNotFoundException e) {  
    }  
    if (stack == null) {  
        if (Build.VERSION.SDK_INT >= 9) {  
            stack = new HurlStack();  
        } else {  
            stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));  
        }  
    }  
    Network network = new BasicNetwork(stack);  
    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);  
    queue.start();  
    return queue;  
}  

可以看到,这里在第10行判断如果stack是等于null的,则去创建一个HttpStack对象,这里会判断如果手机系统版本号是大于9的,则创建一个HurlStack的实例,否则就创建一个HttpClientStack的实例。实际上HurlStack的内部就是使用HttpURLConnection进行网络通讯的,而HttpClientStack的内部则是使用HttpClient进行网络通讯的,这里为什么这样选择呢?可以参考我之前翻译的一篇文章Android访问网络,使用HttpURLConnection还是HttpClient?

 

创建好了HttpStack之后,接下来又创建了一个Network对象,它是用于根据传入的HttpStack对象来处理网络请求的,紧接着new出一个RequestQueue对象,并调用它的start()方法进行启动,然后将RequestQueue返回,这样newRequestQueue()的方法就执行结束了。

 

那么RequestQueue的start()方法内部到底执行了什么东西呢?我们跟进去瞧一瞧:

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值