Volley Source code Analysis
Let's take a look at the source code of volley
Let's see what's Underneath the volley_lib folder.
Outside a package volley, a lot of Java files
Volley also has a package Toolbox, which also has a lot of java files
Where do we start looking?
So , How do we use it , According to the process we use ?
let's take stringrequest as an example .
These Request procedures are the same.
We take stringrequest as an example
The first is to create a stringrequest
Stringrequest stringrequest = new Stringrequest (url,new Response.listener () {},new Response.errorlistener () {});
then we'll find this construction method .
Public stringrequest (String URL, listener<string> Listener, Errorlistener errorlistener) {
This (method.get, URL, Listener, errorlistener);
}
As we can see , He is invoking another method of construction , and then passing a get method
Which means we usually get it by default.
So we found another way to construct it.
Public stringrequest (int method, String URL, listener<string> Listener,
Errorlistener Errorlistener) {
Super (method, URL, errorlistener);
Mlistener = listener;
}
We see
The first is to call the constructor method of the parent class ,
Method,url,errorlistener is passed to the parent class.
and listener gave it to himself.
Gave the mlistener member variable
Our advanced parent Request look inside
Public Request (int method, String URL, Response.errorlistener listener) {
Mmethod = method;
Murl = URL;
Merrorlistener = listener;
Setretrypolicy (New Defaultretrypolicy ());
Mdefaulttrafficstatstag = Textutils.isempty (URL)? 0:uri.parse (URL). GetHost (). Hashcode ();
}
We see
Method,url,errorlistener have given their own member variables
Then call the setretrypolicy, retry the scheme , new a default retry scheme
then create the requestqueue
Volley call newrequestqueue
Requestqueue Requestqueue=volley.newrequestqueue (GetContext ());
In this way, look.
public static Requestqueue Newrequestqueue (context context) {
Return Newrequestqueue (context, NULL);
}
one more level .
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 {
Prior to Gingerbread, HttpURLConnection was unreliable.
See:http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new Httpclientstack (androidhttpclient.newinstance (useragent));
}
}
Network Network = new Basicnetwork (stack);
Requestqueue queue = new Requestqueue (new Diskbasedcache (CACHEDIR), network);
Queue.start ();
return queue;
}
The code here is a little complicated.
Let's take a slow look
We mainly look at the red part
If the stack is not empty
then enter
Then the SDK version is judged
If sdk>=9
Then stack=new hurlstack ();
The hurlstack here is actually httpurlconnection .
Otherwise
Stack=new Httpclientstack (Androidhttpclient.newinstance (useragent));
The httpclientstack here is actually HttpClient .
and then it's new , a basicnetwork .
The basicnetwork here can be seen as a httpurlconnection or HttpClient .
And then created the requestqueue to go back out
Finally, requestqueue calls the add method to send the request
let's go to the add method to see
Public request Add (Request request) {
Tag the request as belonging to this queue and add it to the set of current requests.
Request.setrequestqueue (this);
Synchronized (mcurrentrequests) {
Mcurrentrequests.add (Request);
}
Process requests in the order they is added.
Request.setsequence (Getsequencenumber ());
Request.addmarker ("Add-to-queue");
If the request is uncacheable, skip the cache queue and go straight to the network.
if (!request.shouldcache ()) {
Mnetworkqueue.add (Request);
return request;
}
Insert request to stage if there ' s already a request with the same cache key in flight.
Synchronized (mwaitingrequests) {
String CacheKey = Request.getcachekey ();
if (Mwaitingrequests.containskey (CacheKey)) {
There is already a request in flight. Queue up.
queue<request> stagedrequests = Mwaitingrequests.get (CacheKey);
if (stagedrequests = = null) {
stagedrequests = new linkedlist<request> ();
}
Stagedrequests.add (Request);
Mwaitingrequests.put (CacheKey, stagedrequests);
if (volleylog.debug) {
VOLLEYLOG.V ("Request for cachekey=%s are in flight, putting on hold.", CacheKey);
}
} else {
Insert ' null ' queue for this cacheKey, indicating there are now a request in
Flight.
mwaitingrequests.put (CacheKey, null);
Mcachequeue.add (Request);
}
return request;
}
We're still focusing on the red ones.
First mcurrentrequests added the request
Synchronized (mcurrentrequests) {
Mcurrentrequests.add (Request);
}
What does this mcurrentrequests do?
Mcurrentrequests is used to store all outstanding requests
So all our requests are going through this requests .
finally mwaitingrequests calls the put method
Mwaitingrequests.put (CacheKey, NULL);
Mcachequeue.add (Request);
The mcachequeue here is to store all requests that need to be cached first.
Mwaitingrequests is a request to store the same URL for subsequent initiates
and a mnetworkqueue .
if (!request.shouldcache ()) {
Mnetworkqueue.add (Request);
return request;
}
This is a request that does not fetch the cache , requests the network directly
195_volley Source Code Analysis