Usage of Volley in Android (6) Understanding CacheDispatcher

Source: Internet
Author: User

When you call the add () method of RequestQueue to add a Request, it determines whether to query in the cache based on shouldCache, a Request parameter. If it is to query in the cache, the request will be put in CacheQueue, as shown below:

                mWaitingRequests.put(cacheKey, null);                mCacheQueue.add(request);

At this time, the thread CacheDispatcher is actually running. Let's take a look at it in its run method:

Public void run () {if (DEBUG) VolleyLog. v ("start new dispatcher"); Process. setThreadPriority (Process. THREAD_PRIORITY_BACKGROUND); // initialize the cache mCache. initialize (); while (true) {try {// obtain a final Request from the cache queue
 Request = mCacheQueue. take (); request. addMarker ("cache-queue-take"); // if the request has been canceled, obtain the request if (request. isCanceled () {request. finish ("cache-discard-canceled"); continue;} // obtain the corresponding record Cache from the cache based on the cacheKey of the request. entry entry = mCache. get (request. getCacheKey (); if (entry = null) {request. addMarker ("cache-miss"); // This indicates that there is no corresponding record in the cache. You need to obtain it from the Network and put it in the Network queue mNetworkQueue. put (request); continue;} // if there is a record in the cache but it has expired or expired, you also need to obtain it from the Network and put it in the Network queue if (entry. isExpired () {request. addMarker ("cache-hit-expired"); request. setCacheEntry (entry); mNetworkQueue. put (request); continue;} // If none of the above conditions exist, this indicates that such a record exists in the cache, the request parseNetworkResponse method is called to obtain a Response to the Response request. addMarker ("cache-hit"); Response
 Response = request. parseNetworkResponse (new NetworkResponse (entry. data, entry. responseHeaders); request. addMarker ("cache-hit-parsed"); if (! Entry. refreshNeeded () {// cache record. If no update is required, call mDelivery directly and return it to the main thread for update. MDelivery. postResponse (request, response);} else {// The cache record exists, but the agreed survival time has reached (not completely expired yet, it can be sent to the main thread to update // but it also needs to update its data request from the network. addMarker ("cache-hit-refresh-needed"); request. setCacheEntry (entry); // Mark the response as intermediate. response. intermediate = true; // put the request to the Network queue while returning it to the main thread. MDelivery. postResponse (request, response, new Runnable () {@ Override public void run () {try {mNetworkQueue. put (request);} catch (InterruptedException e) {// Not much we can do about this .}}});}} catch (InterruptedException e) {// We may have been interrupted because it was time to quit. if (mQuit) {return;} continue ;}}}

The cache thread (CacheDispatcher) mainly does the following:

1) initialize the local cache

2) Start an infinite loop and call the take method of mCacheQueue to obtain a request, while mCacheQueue is a BlockingQueue, that is, when no request is sent in the queue, the take method will always be blocked here, waiting for requests in the queue. Once a new request comes in, it will be executed immediately.

    /** The queue of requests coming in for triage. */    private final BlockingQueue
 
  > mCacheQueue;    /** The queue of requests going out to the network. */    private final BlockingQueue
  
   > mNetworkQueue;
  
 

3) determine whether the request has been canceled. If the request has been canceled, you do not need to proceed.

4) Search for the corresponding records in the cache based on the request's CacheKey. If the corresponding record cannot be found or the corresponding record expires, put it in the NetworkQueue queue.

5) if there is a corresponding record in the cache, call the specific implementation method parseNetworkResponse function of each request and parse the Response object according to the specific request.

6) after obtaining the Response object, the system checks whether the request performs a network update. This is based on the recorded soft-ttl (time-to-live) attribute, as shown below:

        /** True if the entry is expired. */        public boolean isExpired() {            return this.ttl < System.currentTimeMillis();        }        /** True if a refresh is needed from the original data source. */        public boolean refreshNeeded() {            return this.softTtl < System.currentTimeMillis();        }

We can also see that the expired judgment and refreshNeed judgment are two fields: ttl and softTtl.

If an update is required, the request will be sent back to the main thread for update, and then put into the NetworkQueue to update the data of the request from the network. If not, call mDelivery to return the result to the main thread for UI update.

CacheDispatcher does not do much, because Volley's main functions are actually dealing with the network, so the main implementation is actually NetworkDispatcher.

End!


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.