Android网络请求2--解析Volley源码

本文大篇幅参考此篇文章,大家可以结合两篇文章看一下

1. Volley简介

在很早以前,如果Android开发者想使用网络请求的话,必须自己通过HttpClient或者HttpURLConnection编写代码来访问。但是他两的用法还是很复杂的,如果不适当的封装的话,就会有很多多余代码甚至效率降低。所以当时出现了很多第三方网络通信框架,但是都是第三方的,而谷歌官方一直没有作为。
最终在2013年,谷歌终于意识到了问题,于是他们推出了一个官方的全新的网络框架——Volley。Volley它又能非常简单的进行HTTP通信,又能轻松加载网络上的图片。他的设计目的就是应对数据量不大但是频发的网络操作,但是对于下载等需要大数据量的网络操作,他就不太适合。

2. 源码解析

2.1 从RequestQueue入手

如果你使用Volley的话,就会发现Volley不管进行什么操作,首先第一步就是先创建RequestQueue对象。
所以我们就可以认定他为Volley的入口。
创建RequestQueue的方法是RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext());,我们就看看newRequestQueue干了什么:

public static RequestQueue newRequestQueue(Context context, BaseHttpStack stack) {
   
    BasicNetwork network;
    if (stack == null) {
   
        if (Build.VERSION.SDK_INT >= 9) {
   
            network = new BasicNetwork(new HurlStack());
        } else {
   
            // 在Android 2.3之前,HttpURLConnection是不可靠的。
            // 请参阅:http://android-developers.blogspot.com/2011/09/androids-http-clients.html
            // 在将来的某个时候,我们将把minsdkversion移到Android 2.2之上,
            // 并可以删除这个回退(连同所有ApacheHTTP代码)。            
            String userAgent = "volley/0";
            try {
   
                String packageName = context.getPackageName();
                PackageInfo info =
             context.getPackageManager().getPackageInfo(packageName, /* flags= */ 0);
                    userAgent = packageName + "/" + info.versionCode;
            } catch (NameNotFoundException e) {
   
            }

        network =
                new BasicNetwork(
                        new HttpClientStack(AndroidHttpClient.newInstance(userAgent)));
        }
    } else {
   
        network = new BasicNetwork(stack);
    }

    return newRequestQueue(context, network);
}

调用方法后,先查看Android版本是否大于等于2.3,如果大于则调用基于HttpURLConnectionHurlStack,否则调用基于HttpClientHttpClientStack。接下来创建BasicNetwork并调用newRequestQueue(context, network)方,我们再来看看这个newRequestQueue()方法:

private static RequestQueue newRequestQueue(Context context, Network network) {
   
    final Context appContext = context.getApplicationContext();
    // 对缓存目录使用惰性供应商,以便可以在主线程上调用newRequestQueue(),
    // 而不会导致严格的模式冲突。    
    DiskBasedCache.FileSupplier cacheSupplier =
            new DiskBasedCache.FileSupplier() {
   
                private File cacheDir = null;

                @Override
                public File get() {
   
                    if (cacheDir == null) {
   
                        cacheDir = new File(appContext.getCacheDir(), DEFAULT_CACHE_DIR);
                    }
                    return cacheDir;
                }
            };
    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheSupplier), network);
    queue.start();
    return queue;
}

可以看到,这个方法主要为Volley创建了一个硬盘缓存DiskBasedCache,然后通过这个磁盘缓存和Network创建了一个RequestQueue对象,并调用了start()方法,接下来我们看下start()方法:

public void start() {
   
    stop(); 
    // 确保当前运行的所有调度程序都已停止。
    // 创建缓存调度器并开始它。
    mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
    mCacheDispatcher.start();

    // 创建达到池大小的网络调度程序(和相应的线程)。
    for (int i = 0; i < mDispatchers.length; i++) {
   
        NetworkDispatcher networkDispatcher =
                    new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery);
        mDispatchers[i] = networkDispatcher;
        networkDispatcher.start();
    }
}

CacheDispatcher是一个缓存调度线程,并调用了start()方法。在循环中调用NetworkDispatcherstart()方法。NetworkDispatcher是网络调度线程,默认情况下mDispatchers.length为4,默认开启了4个调度线程,外加1个缓存调度线程,总共5个线程。
接下来Volley会创建各种Request,并调用RequestQueueadd()方法:

public <T> Request<T> add(Request<T> request) {
   
    // 将请求标记为属于此队列,并将其添加到当前请求集。
    request.setRequestQueue(this);
    synchronized (mCurrentRequests) {
   
        //mCurrentRequests是一个HashSet
        mCurrentRequests.add(request);
    }

    // 按添加的顺序处理请求。
    request.setSequence(getSequenceNumber());
    request.addMarker("add-to-queue");
    sendRequestEvent(request, RequestEvent.REQUEST_QUEUED);

    // 如果请求是不可执行的,跳过缓存队列,然后直接进入网络。
    if (!request.shouldCache()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值