195_Volley源码解析

Volley源码解析

我们来看看Volley的源码

先看看Volley_lib文件夹下面都有些什么东西

外面一个包volley,很多java文件

volley里面还有一个包toolbox,里面也有很多java文件

我们从哪里开始看呢

这样吧,我们怎么用的,就按着使用的流程来看

我们就以StringRequest为例子

这些Request的流程都差不多的

我们以StringRequest为例子

首先是创建了StringRequest

StringRequest stringRequest = new StringRequest(url,new Response.Listener(){},new Response.ErrorListener(){});

那么我们就找到这个构造方法

public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {

this(Method.GET, url, listener, errorListener);

}

我们看到,他是调用了自己的另外一个构造方法,然后传了一个get方法

也就是说我们平时默认是get

那么我们找到另一个构造方法

public StringRequest(int method, String url, Listener<String> listener,

ErrorListener errorListener) {

super(method, url, errorListener);

mListener = listener;

}

我们看到

首先是调用了父类的构造方法,

method,url,errorListener都传给了父类

然后listener给了自己

给了mListener成员变量

我们先进父类Request里面看一看

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();

}

我们看到

method,url,errorListener都给了自己的成员变量

然后调用了setRetryPolicy,重试的方案,new了一个默认的重试方案

接着是创建RequestQueue

Volley调用newRequestQueue

RequestQueue requestQueue=Volley.newRequestQueue(getContext());

进这个方法看看

public static RequestQueue newRequestQueue(Context context) {

return newRequestQueue(context, null);

}

再进一层

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;

}

这里的代码就有点复杂了

我们慢慢看

我们主要看红色部分

如果stack不为空

那么进入

然后判断的是SDK版本

如果SDK>=9

那么stack=new HurlStack();

这里的HurlStack其实就是HttpUrlConnection

否则

stack=new HttpClientStack(AndroidHttpClient.newInstance(userAgent));

这里的HttpClientStack其实就是HttpClient

然后是new了一个BasicNetwork

这里的BasicNetwork可以看做是一个HttpURLConnection或者HttpClient

然后创建了RequestQueue返回出去

最后是RequestQueue调用add方法发送请求

我们进入add方法看看

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 are 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 into 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 is in flight, putting on hold.", cacheKey);

}

} else {

// Insert ‘null‘ queue for this cacheKey, indicating there is now a request in

// flight.

mWaitingRequests.put(cacheKey, null);

mCacheQueue.add(request);

}

return request;

}

我们还是重点看红色部分

先是mCurrentRequests添加了request

synchronized (mCurrentRequests) {

mCurrentRequests.add(request);

}

这个mCurrentRequests是干嘛的呢

mCurrentRequests是用来存储所有未完成的请求

所以我们所有请求发起都要经过这个Requests

最后mWaitingRequests调用put方法

mWaitingRequests.put(cacheKey, null);

mCacheQueue.add(request);

这里的mCacheQueue是存放所有需要先取缓存的请求

mWaitingRequests是存放同一个url后续发起的请求

还有mNetworkQueue

if (!request.shouldCache()) {

mNetworkQueue.add(request);

return request;

}

这是不取缓存,直接请求网络的请求

时间: 2025-01-02 01:37:44

195_Volley源码解析的相关文章

ChrisRenke/DrawerArrowDrawable源码解析

转载请注明出处http://blog.csdn.net/crazy__chen/article/details/46334843 源码下载地址http://download.csdn.net/detail/kangaroo835127729/8765757 这次解析的控件DrawerArrowDrawable是一款侧拉抽屉效果的控件,在很多应用上我们都可以看到(例如知乎),控件的github地址为https://github.com/ChrisRenke/DrawerArrowDrawable

五.jQuery源码解析之jQuery.extend(),jQuery.fn.extend()

给jQuery做过扩展或者制作过jQuery插件的人这两个方法东西可能不陌生.jQuery.extend([deep],target,object1,,object2...[objectN]) jQuery.fn.extend([deep],target,object1,,object2...[objectN])这两个属性都是用于合并两个或多个对象的属性到target对象.deep是布尔值,表示是否进行深度合并,默认是false,不执行深度合并.通过这种方式可以在jQuery或jQuery.fn

eclipse中导入jdk源码、SpringMVC注解@RequestParam、SpringMVC文件上传源码解析、ajax上传excel文件

eclipse中导入jdk源码:http://blog.csdn.net/evolly/article/details/18403321, http://www.codingwhy.com/view/799.html. ------------------------------- SpringMVC注解@RequestParam:http://825635381.iteye.com/blog/2196911. --------------------------- SpringMVC文件上传源

String源码解析(一)

本篇文章内的方法介绍,在方法的上面的注释讲解的很清楚,这里只阐述一些要点. Java中的String类的定义如下: 1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { ...} 可以看到,String是final的,而且继承了Serializable.Comparable和CharSequence接口. 正是因为这个特性,字符串对象可以被共享,例如下面

Flume-ng源码解析之Channel组件

如果还没看过Flume-ng源码解析之启动流程,可以点击Flume-ng源码解析之启动流程 查看 1 接口介绍 组件的分析顺序是按照上一篇中启动顺序来分析的,首先是Channel,然后是Sink,最后是Source,在开始看组件源码之前我们先来看一下两个重要的接口,一个是LifecycleAware ,另一个是NamedComponent 1.1 LifecycleAware @[email protected] interface LifecycleAware {  public void s

Spring源码解析-applicationContext

Demo uml类图 ApplicationContext ApplicationListener 源码解析 主流程 obtainFreshBeanFactory prepareBeanFactory invokeBeanFactoryPostProcessors registerBeanPostProcessors registerListeners finishRefresh 总结 在已经有BeanFactory可以完成Ioc功能情况下,spring又提供了ApplicationContex

socketserver源码解析和协程版socketserver

来,贴上一段代码让你仰慕一下欧socketserver的魅力,看欧怎么完美实现多并发的魅力 client import socket ip_port = ('127.0.0.1',8009) sk = socket.socket() sk.connect(ip_port) sk.settimeout(5) while True: data = sk.recv(1024) print('receive:',data.decode()) inp = input('please input:') sk

Handler机制(四)---Handler源码解析

Handler的主要用途有两个:(1).在将来的某个时刻执行消息或一个runnable,(2)把消息发送到消息队列. 主要依靠post(Runnable).postAtTime(Runnable, long).postDelayed(Runnable, long).sendEmptyMessage(int).sendMessage(Message).sendMessageAtTime(Message).sendMessageDelayed(Message, long)这些方法来来完成消息调度.p

Android EventBus源码解析, 带你深入理解EventBus

上一篇带大家初步了解了EventBus的使用方式,详见:Android EventBus实战 没听过你就out了,本篇博客将解析EventBus的源码,相信能够让大家深入理解该框架的实现,也能解决很多在使用中的疑问:为什么可以这么做?为什么这么做不好呢? 1.概述 一般使用EventBus的组件类,类似下面这种方式: [java] view plain copy public class SampleComponent extends Fragment { @Override public vo