深入剖析Android的Volley框架中的图片加载功能

2019-12-10 18:25:44于丽

ok,首先要明确这个缓存指的是硬盘缓存(目录为context.getCacheDir()/volley),内存缓存在ImageLoader那里已经判断过了。

可以看到这里是个无限循环,不断的从mCacheQueue去取出请求,如果请求已经被取消就直接结束;

接下来从缓存中获取:

=>如果没有取到,则加入mNetworkQueue

=>如果缓存过期,则加入mNetworkQueue

否则,就是取到了可用的缓存了;调用request.parseNetworkResponse解析从缓存中取出的data和responseHeaders;接下来判断TTL(主要还是判断是否过期),如果没有过期则直接通过mDelivery.postResponse转发,然后回调到UI线程;如果ttl不合法,回调完成后,还会将该请求加入mNetworkQueue。

好了,这里其实就是如果拿到合法的缓存,则直接转发到UI线程;反之,则加入到NetworkQueue.

接下来我们看NetworkDispatcher。

(五)NetworkDispatcher

与CacheDispatcher类似,依然是个线程,核心代码依然在run中;

# NetworkDispatcher
//new NetworkDispatcher(mNetworkQueue, mNetwork,mCache, mDelivery)

public NetworkDispatcher(BlockingQueue<Request<?>> queue,
      Network network, Cache cache,
      ResponseDelivery delivery) {
    mQueue = queue;
    mNetwork = network;
    mCache = cache;
    mDelivery = delivery;
  }
@Override
  public void run() {
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    while (true) {
      long startTimeMs = SystemClock.elapsedRealtime();
      Request<?> request;
      try {
        // Take a request from the queue.
        request = mQueue.take();
      } catch (InterruptedException e) {
        // We may have been interrupted because it was time to quit.
        if (mQuit) {
          return;
        }
        continue;
      }

      try {
        request.addMarker("network-queue-take");

        // If the request was cancelled already, do not perform the
        // network request.
        if (request.isCanceled()) {
          request.finish("network-discard-cancelled");
          continue;
        }

        addTrafficStatsTag(request);

        // Perform the network request.
        NetworkResponse networkResponse = mNetwork.performRequest(request);
        request.addMarker("network-http-complete");

        // If the server returned 304 AND we delivered a response already,
        // we're done -- don't deliver a second identical response.
        if (networkResponse.notModified && request.hasHadResponseDelivered()) {
          request.finish("not-modified");
          continue;
        }

        // Parse the response here on the worker thread.
        Response<?> response = request.parseNetworkResponse(networkResponse);
        request.addMarker("network-parse-complete");

        // Write to cache if applicable.
        // TODO: Only update cache metadata instead of entire record for 304s.
        if (request.shouldCache() && response.cacheEntry != null) {
          mCache.put(request.getCacheKey(), response.cacheEntry);
          request.addMarker("network-cache-written");
        }

        // Post the response back.
        request.markDelivered();
        mDelivery.postResponse(request, response);
      } catch (VolleyError volleyError) {
        volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
        parseAndDeliverNetworkError(request, volleyError);
      } catch (Exception e) {
        VolleyLog.e(e, "Unhandled exception %s", e.toString());
        VolleyError volleyError = new VolleyError(e);
        volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
        mDelivery.postError(request, volleyError);
      }
    }
  }