Volley请求源码解读 (1) ---无缓存请求

在使用Volley进行网络请求时,我们只需要调用一句mVolleyRequestQueue.add(mRequest);就可以开始网络请求了,这个过程是怎么样的呢,来看一下源码:

public <T> Request<T> add(Request<T> request) {
        request.setRequestQueue(this);
        synchronized (mCurrentRequests) {
            mCurrentRequests.add(request);//这个mCurrentRequests是一个HashSet
        }
        request.setSequence(getSequenceNumber());
        request.addMarker("add-to-queue");
        if (!request.shouldCache()) {
            mNetworkQueue.add(request);//这个mNetworkQueue是一个PriorityBlockingQueue<Request<?>>
            return request;
        }
        /*以下是有缓存的情况,先省略不写*/
}

可以看到,RequestQueue类里有一个HashSet:mCurrentRequests,和一个 PriorityBlockingQueue:mNetworkQueue
在add请求时,把这个请求添加到了这个set和mNetworkQueue中去了
到这里,消息已经添加到请求队列中去了

用Volley.newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes)创建RequestQueue实例时:

public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes) {
      if (stack == null) {
          if (Build.VERSION.SDK_INT >= 9) {//这句在api 9及以上都用,因此基本上stack 就是 HurlStack ,这个是最终进行网络请求的类,后面再说
              stack = new HurlStack();
          } else {
              stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }
      Network network = new BasicNetwork(stack);
      RequestQueue queue;
      queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);//这个方法最终会调用RequestQueue(Cache cache, Network network, int threadPoolSize,ResponseDelivery delivery)
      queue.start();
      return queue;
    }

在这里通过start启动了queue

看一下RequestQueue(Cache cache, Network network, int threadPoolSize,ResponseDelivery delivery):

public RequestQueue(Cache cache, Network network, int threadPoolSize,
            ResponseDelivery delivery) {
        mCache = cache;
        mNetwork = network;
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        mDelivery = delivery;
    }

可以看到,RequestQueue最终维护了一个NetworkDispatcher数组,这个数组的长度默认为4,从命名可以看出,这是这个队列维护的线程数,第二个参数实际上是Volley利用stack参数给RequestQueue提供的一个Network network = new BasicNetwork(stack),

来看queue的start方法

public void start() {
        for (int i = 0; i < mDispatchers.length; i++) {
            NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery);
            mDispatchers[i] = networkDispatcher;
            networkDispatcher.start();
        }
    }

实际上是启动了N个NetworkDispatcher,这个类继承了Thread类,NetworkDispatcher最终调用本地方法nativeCreate(this, stackSize, daemon)这个看不懂,但是NetworkDispatcher有个run方法,最终应该是调用run,来看一下源码,实际上是一个死循环,不断从取消息,如有则使用mNetwork.performRequest来进行请求

public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        Request<?> request;
        while (true) {
            request = null;
            request = mQueue.take();
            NetworkResponse networkResponse = mNetwork.performRequest(request);
        }
    }

调用了mNetwork的performRequest,就是前面提供的BasicNetwork

public NetworkResponse performRequest(Request<?> request) throws VolleyError {
    //前面提到,这个stack实际上是一个HurlStack()
        httpResponse = mHttpStack.performRequest(request, headers);
}

HurlStack()中的performRequest:

public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
            throws IOException, AuthFailureError {
        String url = request.getUrl();
        HashMap<String, String> map = new HashMap<String, String>();
        map.putAll(request.getHeaders());
        map.putAll(additionalHeaders);
        if (mUrlRewriter != null) {
            String rewritten = mUrlRewriter.rewriteUrl(url);
            if (rewritten == null) {
                throw new IOException("URL blocked by rewriter: " + url);
            }
            url = rewritten;
        }
        URL parsedUrl = new URL(url);
        HttpURLConnection connection = openConnection(parsedUrl, request);
        for (String headerName : map.keySet()) {
            connection.addRequestProperty(headerName, map.get(headerName));
        }
        setConnectionParametersForRequest(connection, request);

        ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
        int responseCode = connection.getResponseCode();
        if (responseCode == -1) {
            throw new IOException("Could not retrieve response code from HttpUrlConnection.");
        }
        StatusLine responseStatus = new BasicStatusLine(protocolVersion,
                connection.getResponseCode(), connection.getResponseMessage());
        BasicHttpResponse response = new BasicHttpResponse(responseStatus);
        if (hasResponseBody(request.getMethod(), responseStatus.getStatusCode())) {
            response.setEntity(entityFromConnection(connection));
        }
        for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
            if (header.getKey() != null) {
                Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
                response.addHeader(h);
            }
        }
        return response;
    }

可以看到,最终是用HttpUrlConnection进行了网络请求。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值