0%

Volley源码解析

概述

本文基于Volley 1.1.1版本的源码。

Volley是Google官方出的一套小而巧的异步请求库,该框架封装的扩展性很强,支持HttpClient、HttpUrlConnection,甚至支持OkHttp。Volley不适用于下载大量内容的操作或流式传输操作,因为在解析过程中,Volley会将所有响应存储在内存中,因此Volley不适合上传和下载大文件。

添加依赖:

1
implementation 'com.android.volley:volley:1.1.1'

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
RequestQueue queue = Volley.newRequestQueue(context);
String url ="http://www.google.com";

StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// in UI Thread
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// in UI Thread
}
});
stringRequest.setTag(TAG);

// Add the request to the RequestQueue.
queue.add(stringRequest);

// onStop
queue.cancelAll(TAG);

创建请求队列

Volley类中有多个重载的newRequestQueue静态方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Volley {
private static final String DEFAULT_CACHE_DIR = "volley";

public static RequestQueue newRequestQueue(Context context) {
return newRequestQueue(context, (BaseHttpStack) null);
}

public static RequestQueue newRequestQueue(Context context, BaseHttpStack stack) {
BasicNetwork network;
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
network = new BasicNetwork(new HurlStack());
} else {
// ...
}
} else {
network = new BasicNetwork(stack);
}

return newRequestQueue(context, network);
}

private static RequestQueue newRequestQueue(Context context, Network network) {
final Context appContext = context.getApplicationContext();
DiskBasedCache.FileSupplier cacheSupplier =
new DiskBasedCache.FileSupplier() {
private File cacheDir = null;

@Override
public File get() {
if (cacheDir == null) {
cacheDir = new File(appContext.getCacheDir(), DEFAULT_CACHE_DIR);
}
return cacheDir;
}
};
RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheSupplier), network);
queue.start();
return queue;
}
}

RequestQueue类构造方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class RequestQueue {
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4;
private final Cache mCache;
private final Network mNetwork;
private final ResponseDelivery mDelivery;
private final NetworkDispatcher[] mDispatchers;
private CacheDispatcher mCacheDispatcher;

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

public RequestQueue(Cache cache, Network network, int threadPoolSize) {
this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper())));
}

public RequestQueue(Cache cache, Network network) {
this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
}
}

RequestQueue#start()方法如下,可以看出就是启动了一个Cache Dispatcher和指定数目的Network Dispatcher:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/** Starts the dispatchers in this queue. */
public void start() {
// Make sure any currently running dispatchers are stopped.
stop();
// Create the cache dispatcher and start it.
mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
mCacheDispatcher.start();

// Create network dispatchers (and corresponding threads) up to the pool size.
for (int i = 0; i < mDispatchers.length; i++) {
NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery);
mDispatchers[i] = networkDispatcher;
networkDispatcher.start();
}
}

/** Stops the cache and network dispatchers. */
public void stop() {
if (mCacheDispatcher != null) {
mCacheDispatcher.quit();
}
for (final NetworkDispatcher mDispatcher : mDispatchers) {
if (mDispatcher != null) {
mDispatcher.quit();
}
}
}

RequestQueue事件

在RequestQueue类中定义了一些事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public @interface RequestEvent {
/** The request was added to the queue. */
public static final int REQUEST_QUEUED = 0;
/** Cache lookup started for the request. */
public static final int REQUEST_CACHE_LOOKUP_STARTED = 1;
/** Cache lookup finished for the request and cached response is delivered or request is queued for network dispatching. */
public static final int REQUEST_CACHE_LOOKUP_FINISHED = 2;
/** Network dispatch started for the request. */
public static final int REQUEST_NETWORK_DISPATCH_STARTED = 3;
/** The network dispatch finished for the request and response (if any) is delivered. */
public static final int REQUEST_NETWORK_DISPATCH_FINISHED = 4;
/** All the work associated with the request is finished and request is removed from all the queues. */
public static final int REQUEST_FINISHED = 5;
}

public interface RequestEventListener {
void onRequestEvent(Request<?> request, @RequestEvent int event);
}

private final List<RequestEventListener> mEventListeners = new ArrayList<>();

可以通过下面几个方法操作这些事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void sendRequestEvent(Request<?> request, @RequestEvent int event) {
synchronized (mEventListeners) {
for (RequestEventListener listener : mEventListeners) {
listener.onRequestEvent(request, event);
}
}
}

public void addRequestEventListener(RequestEventListener listener) {
synchronized (mEventListeners) {
mEventListeners.add(listener);
}
}

public void removeRequestEventListener(RequestEventListener listener) {
synchronized (mEventListeners) {
mEventListeners.remove(listener);
}
}

发送请求

RequestQueue#add()方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private final AtomicInteger mSequenceGenerator = new AtomicInteger();
private final Set<Request<?>> mCurrentRequests = new HashSet<>();
private final PriorityBlockingQueue<Request<?>> mCacheQueue = new PriorityBlockingQueue<>();
private final PriorityBlockingQueue<Request<?>> mNetworkQueue = new PriorityBlockingQueue<>();

public <T> Request<T> add(Request<T> 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");
sendRequestEvent(request, RequestEvent.REQUEST_QUEUED);

// 如果请求不需要缓存的话,直接交给网络请求队列去执行,默认是需要缓存的
if (!request.shouldCache()) {
mNetworkQueue.add(request);
return request;
}
mCacheQueue.add(request);
return request;
}

在这个方法中把请求交给了缓存队列或者网络队列去处理。

CacheDispatcher

CacheDispatcher继承自Thread,在RequestQueue#start()方法中已经将其启动了,因此直接看run方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
public class CacheDispatcher extends Thread {
private final BlockingQueue<Request<?>> mCacheQueue;
private final BlockingQueue<Request<?>> mNetworkQueue;
private final Cache mCache;
private final ResponseDelivery mDelivery;
private volatile boolean mQuit = false;

/** Manage list of waiting requests and de-duplicate requests with same cache key. */
private final WaitingRequestManager mWaitingRequestManager;

public CacheDispatcher(
BlockingQueue<Request<?>> cacheQueue,
BlockingQueue<Request<?>> networkQueue,
Cache cache,
ResponseDelivery delivery) {
mCacheQueue = cacheQueue;
mNetworkQueue = networkQueue;
mCache = cache;
mDelivery = delivery;
mWaitingRequestManager = new WaitingRequestManager(this);
}

public void quit() {
mQuit = true;
interrupt();
}

@Override
public void run() {
if (DEBUG) VolleyLog.v("start new dispatcher");
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

// Make a blocking call to initialize the cache.
mCache.initialize();

while (true) {
try {
processRequest();
} catch (InterruptedException e) {
// We may have been interrupted because it was time to quit.
if (mQuit) {
Thread.currentThread().interrupt();
return;
}
VolleyLog.e("Ignoring spurious interrupt of CacheDispatcher thread; " + "use quit() to terminate it");
}
}
}

private void processRequest() throws InterruptedException {
// 阻塞式队列
final Request<?> request = mCacheQueue.take();
processRequest(request);
}

void processRequest(final Request<?> request) throws InterruptedException {
request.addMarker("cache-queue-take");
request.sendEvent(RequestQueue.RequestEvent.REQUEST_CACHE_LOOKUP_STARTED);

try {
// If the request has been canceled, don't bother dispatching it.
if (request.isCanceled()) {
request.finish("cache-discard-canceled");
return;
}

// Attempt to retrieve this item from cache.
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) {
request.addMarker("cache-miss");
// Cache miss; send off to the network dispatcher.
if (!mWaitingRequestManager.maybeAddToWaitingRequests(request)) {
mNetworkQueue.put(request);
}
return;
}

// If it is completely expired, just send it to the network.
if (entry.isExpired()) {
request.addMarker("cache-hit-expired");
request.setCacheEntry(entry);
if (!mWaitingRequestManager.maybeAddToWaitingRequests(request)) {
mNetworkQueue.put(request);
}
return;
}

// We have a cache hit; parse its data for delivery back to the request.
request.addMarker("cache-hit");
Response<?> response = request.parseNetworkResponse(new NetworkResponse(entry.data, entry.responseHeaders));
request.addMarker("cache-hit-parsed");

if (!response.isSuccess()) {
request.addMarker("cache-parsing-failed");
mCache.invalidate(request.getCacheKey(), true);
request.setCacheEntry(null);
if (!mWaitingRequestManager.maybeAddToWaitingRequests(request)) {
mNetworkQueue.put(request);
}
return;
}
if (!entry.refreshNeeded()) {
// 缓存不需要刷新,直接交给ResponseDelivery去处理
mDelivery.postResponse(request, response);
} else {
// 软过期的缓存命中,可以分发缓存的response,但是我们还需要将请求发送到网络以进行刷新。
request.addMarker("cache-hit-refresh-needed");
request.setCacheEntry(entry);
// Mark the response as intermediate.
response.intermediate = true;

if (!mWaitingRequestManager.maybeAddToWaitingRequests(request)) {
// 将intermediate响应发回给用户,然后将请求转发到网络。
mDelivery.postResponse(
request,
response,
new Runnable() {
@Override
public void run() {
try {
// 如果缓存需要刷新,这个地方还需要再重新请求网络
mNetworkQueue.put(request);
} catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
});
} else {
// 该请求已添加到等待请求的列表中,以便在第一个请求返回时从第一个请求接收网络响应。
mDelivery.postResponse(request, response);
}
}
} finally {
request.sendEvent(RequestQueue.RequestEvent.REQUEST_CACHE_LOOKUP_FINISHED);
}
}
}

如果有缓存,就取出来去处理,没有或者过期等,就加入到网络请求队列中去请求,需要网络请求的有几个地方:

  1. 请求不需要缓存
  2. 请求在缓存中没有找到
  3. 请求的缓存过期
  4. 请求的缓存需要刷新

NetworkDispatcher

NetworkDispatcher

NetworkDispatcher也继承自Thread,它们在RequestQueue#start()方法中已经被启动了,因此直接看run方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
public class NetworkDispatcher extends Thread {
private final BlockingQueue<Request<?>> mQueue;
private final Network mNetwork;
private final Cache mCache;
private final ResponseDelivery mDelivery;
private volatile boolean mQuit = false;

public NetworkDispatcher(
BlockingQueue<Request<?>> queue,
Network network,
Cache cache,
ResponseDelivery delivery) {
mQueue = queue;
mNetwork = network;
mCache = cache;
mDelivery = delivery;
}

public void quit() {
mQuit = true;
interrupt();
}

@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
while (true) {
try {
processRequest();
} catch (InterruptedException e) {
// We may have been interrupted because it was time to quit.
if (mQuit) {
Thread.currentThread().interrupt();
return;
}
VolleyLog.e("Ignoring spurious interrupt of NetworkDispatcher thread; " + "use quit() to terminate it");
}
}
}

private void processRequest() throws InterruptedException {
Request<?> request = mQueue.take();
processRequest(request);
}

void processRequest(Request<?> request) {
long startTimeMs = SystemClock.elapsedRealtime();
request.sendEvent(RequestQueue.RequestEvent.REQUEST_NETWORK_DISPATCH_STARTED);
try {
request.addMarker("network-queue-take");

if (request.isCanceled()) {
request.finish("network-discard-cancelled");
request.notifyListenerResponseNotUsable();
return;
}

addTrafficStatsTag(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");
request.notifyListenerResponseNotUsable();
return;
}

// 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);
request.notifyListenerResponseReceived(response);
} catch (VolleyError volleyError) {
volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
parseAndDeliverNetworkError(request, volleyError);
request.notifyListenerResponseNotUsable();
} 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);
request.notifyListenerResponseNotUsable();
} finally {
request.sendEvent(RequestQueue.RequestEvent.REQUEST_NETWORK_DISPATCH_FINISHED);
}
}
}

可以看到,在NetworkDispatcher中,最主要的就是调用了mNetwork.performRequest(request)执行网络请求,而在Network是个接口,具体实现类是BasicNetwork。

BasicNetwork

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public NetworkResponse performRequest(Request<?> request) throws VolleyError {
long requestStart = SystemClock.elapsedRealtime();
while (true) {
// ...
try {
// ...
httpResponse = mBaseHttpStack.executeRequest(request, additionalRequestHeaders);
// return NetworkResponse
} catch (SocketTimeoutException e) {
attemptRetryOnException("socket", request, new TimeoutError());
} catch (MalformedURLException e) {
throw new RuntimeException("Bad URL " + request.getUrl(), e);
} catch (IOException e) {
int statusCode;
if (httpResponse != null) {
statusCode = httpResponse.getStatusCode();
} else {
throw new NoConnectionError(e);
}
VolleyLog.e("Unexpected response code %d for %s", statusCode, request.getUrl());
NetworkResponse networkResponse;
if (responseContents != null) {
networkResponse =
new NetworkResponse(
statusCode,
responseContents,
/* notModified= */ false,
SystemClock.elapsedRealtime() - requestStart,
responseHeaders);
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED
|| statusCode == HttpURLConnection.HTTP_FORBIDDEN) {
attemptRetryOnException(
"auth", request, new AuthFailureError(networkResponse));
} else if (statusCode >= 400 && statusCode <= 499) {
// Don't retry other client errors.
throw new ClientError(networkResponse);
} else if (statusCode >= 500 && statusCode <= 599) {
if (request.shouldRetryServerErrors()) {
attemptRetryOnException(
"server", request, new ServerError(networkResponse));
} else {
throw new ServerError(networkResponse);
}
} else {
// 3xx? No reason to retry.
throw new ServerError(networkResponse);
}
} else {
attemptRetryOnException("network", request, new NetworkError());
}
}
}
}

// 请求重试
private static void attemptRetryOnException(
String logPrefix, Request<?> request, VolleyError exception) throws VolleyError {
RetryPolicy retryPolicy = request.getRetryPolicy();
int oldTimeout = request.getTimeoutMs();

try {
retryPolicy.retry(exception);
} catch (VolleyError e) {
request.addMarker(String.format("%s-timeout-giveup [timeout=%s]", logPrefix, oldTimeout));
throw e;
}
request.addMarker(String.format("%s-retry [timeout=%s]", logPrefix, oldTimeout));
}

public class DefaultRetryPolicy implements RetryPolicy {
@Override
public void retry(VolleyError error) throws VolleyError {
mCurrentRetryCount++;
mCurrentTimeoutMs += (int) (mCurrentTimeoutMs * mBackoffMultiplier);
if (!hasAttemptRemaining()) {
throw error;
}
}

/** Returns true if this policy has attempts remaining, false otherwise. */
protected boolean hasAttemptRemaining() {
return mCurrentRetryCount <= mMaxNumRetries;
}
}

在BasicNetwork#performRequest()中调用了httpResponse = mBaseHttpStack.executeRequest(request, additionalRequestHeaders);,这里的mBaseHttpStack就是前面创建RequestQueue时新建的HurlStack和HttpClientStack(@Deprecated,上面RequestQueue的构造函数中还有个新建了HttpClientStack对象的方法,不过已经废弃了,不做解析)。因此在 HttpStack的executeRequest()中就是具体的网络请求。

HurlStack

1
2
3
4
5
6
7
public class HurlStack extends BaseHttpStack {
@Override
public HttpResponse executeRequest(Request<?> request, Map<String, String> additionalHeaders)
throws IOException, AuthFailureError {
// 这个类是使用HttpURLConnection来实现真的的网络请求,可以自定义
}
}

ResponseDelivery

ResponseDelivery是一个接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface ResponseDelivery {
/** Parses a response from the network or cache and delivers it. */
void postResponse(Request<?> request, Response<?> response);

/**
* Parses a response from the network or cache and delivers it. The provided Runnable will be
* executed after delivery.
*/
void postResponse(Request<?> request, Response<?> response, Runnable runnable);

/** Posts an error for the given request. */
void postError(Request<?> request, VolleyError error);
}

具体实现类是ExecutorDelivery,它保证了客户端调用的回调运行在UI线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class ExecutorDelivery implements ResponseDelivery {
private final Executor mResponsePoster;
// 在上面的分析中可以看到这里的handle = new Handler(Looper.getMainLooper())
public ExecutorDelivery(final Handler handler) {
mResponsePoster = new Executor() {
@Override
public void execute(Runnable command) {
handler.post(command);
}
};
}

public ExecutorDelivery(Executor executor) {
mResponsePoster = executor;
}

@Override
public void postResponse(Request<?> request, Response<?> response) {
postResponse(request, response, null);
}

@Override
public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
request.markDelivered();
request.addMarker("post-response");
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
}

@Override
public void postError(Request<?> request, VolleyError error) {
request.addMarker("post-error");
Response<?> response = Response.error(error);
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
}

private static class ResponseDeliveryRunnable implements Runnable {
private final Request mRequest;
private final Response mResponse;
private final Runnable mRunnable;

public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
mRequest = request;
mResponse = response;
mRunnable = runnable;
}

@SuppressWarnings("unchecked")
@Override
public void run() {
if (mRequest.isCanceled()) {
mRequest.finish("canceled-at-delivery");
return;
}

// 这里会调用在创建Request时传入的回调
if (mResponse.isSuccess()) {
mRequest.deliverResponse(mResponse.result);
} else {
mRequest.deliverError(mResponse.error);
}

if (mResponse.intermediate) {
mRequest.addMarker("intermediate-response");
} else {
mRequest.finish("done");
}

// 如果有需要执行的任务,如前面缓存需要刷新等,就会在这个地方进行调用
if (mRunnable != null) {
mRunnable.run();
}
}
}
}

总结

Volley中主要的类有这些:

  • Volley: 提供了构建RequestQueue的统一方法,我们也可以不通过Volley类而是自己构建RequestQueue;
  • RequestQueue: 负责分发请求到不同的请求队列中;
  • CacheDispatcher: 处理缓存请求;
  • NetworkDispatcher: 处理网络请求;
  • ResponseDelivery: 获取请求后进行处理,具体实现类为ExecutorDelivery;
  • Cache: 缓存接口,具体实现类有DiskBasedCache;
  • Network: 网络接口,具体实现类有BasicNetwork;
  • HttpStack: 真正执行请求,具体实现类有HttpClientStack(已废弃),BaseHttpStack(子类有HurlStack,AdaptedHttpStack等);
  • Request: 封装请求信息并处理回调,具体实现类有StringRequest,JsonRequest,ImageRequest等;
  • NetworkResponse:请求网络时的返回的response;
  • Response: 定义了一些回调接口,用来封装返回给客户端的数据。

Volley框架的拆装性很强,可以使用许多我们自定义的类来扩展其功能:

  • Request:框架默认提供了StringRequest,JsonRequest和ImageRequest等,我们可以继承Request并重写deliverResponse()和parseNetworkResponse()来自定义请求。
  • Cache:框架默认提供了DiskBasedCache类来处理缓存,我们可以继承Cache接口来自定义缓存策略。
  • HttpStack:框架默认使用的HurlStack类是通过HttpUrlConnection和HttpClient来实现网络请求,我们可以换成其它的比如说OkHttp,只需要继承HttpStack并重写performRequest()来处理请求就可以了。

总结一下Volley网络请求的流程:

  • 首先创建请求队列RequestQueue,其中可以自定义相关类,在这里会启动了一个Cache Dispatcher和指定数目的Network Dispatcher;
  • 然后在CacheDispatcher中处理请求,若缓存可用,则直接返回缓存,否则请求网络;
  • 接着在NetworkDispatcher中处理网络请求,真正起作用的是HttpStack实现类;
  • 最后通过ResponseDelivery实现类返回请求结果。