android-async-http框架源码分析详解手机开发

async-http使用地址

android-async-http仓库:git clone https://github.com/loopj/android-async-http

源码分析

我们在做网络请求的时候经常通过下面的方式实例化AsyncHttpClient client=new AsyncHttpClient();然后通过系统内置的请求发送请求,通过async内部的请求去做真正的网络请求。

首先得到的是AsyncHttpClient实例,所以从这里入手分析一下:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** 
     * Creates a new AsyncHttpClient with default constructor arguments values 
     */ 
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public <span class="hljs-title" style="box-sizing: border-box;">AsyncHttpClient() { 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">80, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">443); 
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

对于默认值设置了HTTP协议的默认端口为80,HTTPS协议的默认端口为443。

在该函数中调用了AsyncHttpClient(SchemeRegistry schemeRegistry)构造函数,而真正的实例化获取逻辑过程就在AsyncHttpClient(SchemeRegistry schemeRegistry)方法中,如下所示:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** 
* Creates a new AsyncHttpClient. 
* 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param schemeRegistry SchemeRegistry to be used 
*/ 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public <span class="hljs-title" style="box-sizing: border-box;">AsyncHttpClient(SchemeRegistry schemeRegistry) { 
BasicHttpParams httpParams = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new BasicHttpParams(); 
ConnManagerParams.setTimeout(httpParams, connectTimeout); 
ConnManagerParams.setMaxConnectionsPerRoute(httpParams, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new ConnPerRouteBean(maxConnections)); 
ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS); 
HttpConnectionParams.setSoTimeout(httpParams, responseTimeout); 
HttpConnectionParams.setConnectionTimeout(httpParams, connectTimeout); 
HttpConnectionParams.setTcpNoDelay(httpParams, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true); 
HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE); 
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1); 
ClientConnectionManager cm = createConnectionManager(schemeRegistry, httpParams); 
Utils.asserts(cm != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Custom implementation of #createConnectionManager(SchemeRegistry, BasicHttpParams) returned null"); 
threadPool = getDefaultThreadPool(); 
requestMap = Collections.synchronizedMap(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new WeakHashMap<Context, List<RequestHandle>>()); 
clientHeaderMap = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new HashMap<String, String>(); 
httpContext = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new SyncBasicHttpContext(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new BasicHttpContext()); 
httpClient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new DefaultHttpClient(cm, httpParams); 
httpClient.addRequestInterceptor(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new HttpRequestInterceptor() { 
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void <span class="hljs-title" style="box-sizing: border-box;">process(HttpRequest request, HttpContext context) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (!request.containsHeader(HEADER_ACCEPT_ENCODING)) { 
request.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP); 
} 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for (String header : clientHeaderMap.keySet()) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (request.containsHeader(header)) { 
Header overwritten = request.getFirstHeader(header); 
Log.d(LOG_TAG, 
String.format(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Headers were overwritten! (%s | %s) overwrites (%s | %s)", 
header, clientHeaderMap.get(header), 
overwritten.getName(), overwritten.getValue()) 
); 
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//remove the overwritten header 
request.removeHeader(overwritten); 
} 
request.addHeader(header, clientHeaderMap.get(header)); 
} 
} 
}); 
httpClient.addResponseInterceptor(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new HttpResponseInterceptor() { 
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void <span class="hljs-title" style="box-sizing: border-box;">process(HttpResponse response, HttpContext context) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final HttpEntity entity = response.getEntity(); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (entity == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return; 
} 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final Header encoding = entity.getContentEncoding(); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (encoding != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for (HeaderElement element : encoding.getElements()) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (element.getName().equalsIgnoreCase(ENCODING_GZIP)) { 
response.setEntity(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new InflatingEntity(entity)); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break; 
} 
} 
} 
} 
}); 
httpClient.addRequestInterceptor(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new HttpRequestInterceptor() { 
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void <span class="hljs-title" style="box-sizing: border-box;">process(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final HttpRequest request, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final HttpContext context) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws HttpException, IOException { 
AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); 
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute( 
ClientContext.CREDS_PROVIDER); 
HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (authState.getAuthScheme() == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
AuthScope authScope = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new AuthScope(targetHost.getHostName(), targetHost.getPort()); 
Credentials creds = credsProvider.getCredentials(authScope); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (creds != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
authState.setAuthScheme(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new BasicScheme()); 
authState.setCredentials(creds); 
} 
} 
} 
}, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0); 
httpClient.setHttpRequestRetryHandler(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new RetryHandler(DEFAULT_MAX_RETRIES, DEFAULT_RETRY_SLEEP_TIME_MILLIS)); 
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li></ul>

从代码的最顶层分析,构造参数传入的是SchemeRegistry对象,查看源码这是一个静态的方法,主要存储一些协议的东西

 public SchemeRegistry() {
        super();
        registeredSchemes = new ConcurrentHashMap<String,Scheme>();
    }

上面的代码我们主要关注下addResponseInterceptor和addResponseInterceptor,此两个方法主要将我们的请求头和请求的实体加到HttpRequest队列中,对android1.5之前的熟悉的朋友都知道,在最早之前没有流行这些第三方之前我们就是通过HttpRequest来请求的,这等同于j2ee的HttpServletRequest.

接下来我们调运的就是AsyncHttpClient里面的各种get、post、delete等方法,通过看代码可以发现它们最终调用的都是sendRequest方法,如下:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** 
* Puts a new request in queue as a new thread in pool to be executed 
* 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param client          HttpClient to be used for request, can differ in single requests 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param contentType     MIME body type, for POST and PUT requests, may be null 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param context         Context of Android application, to hold the reference of request 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param httpContext     HttpContext in which the request will be executed 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param responseHandler ResponseHandler or its subclass to put the response into 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param uriRequest      instance of HttpUriRequest, which means it must be of HttpDelete, 
*                        HttpPost, HttpGet, HttpPut, etc. 
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @return RequestHandle of future request process 
*/ 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected RequestHandle <span class="hljs-title" style="box-sizing: border-box;">sendRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, ResponseHandlerInterface responseHandler, Context context) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (uriRequest == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"HttpUriRequest must not be null"); 
} 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (responseHandler == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ResponseHandler must not be null"); 
} 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (responseHandler.getUseSynchronousMode() && !responseHandler.getUsePoolThread()) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead."); 
} 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (contentType != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (uriRequest <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof HttpEntityEnclosingRequestBase && ((HttpEntityEnclosingRequestBase) uriRequest).getEntity() != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
Log.w(LOG_TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Passed contentType will be ignored because HttpEntity sets content type"); 
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else { 
uriRequest.setHeader(HEADER_CONTENT_TYPE, contentType); 
} 
} 
responseHandler.setRequestHeaders(uriRequest.getAllHeaders()); 
responseHandler.setRequestURI(uriRequest.getURI()); 
AsyncHttpRequest request = newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context); 
threadPool.submit(request); 
RequestHandle requestHandle = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new RequestHandle(request); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (context != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Add request to request map 
List<RequestHandle> requestList = requestMap.get(context); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized (requestMap) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (requestList == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null) { 
requestList = Collections.synchronizedList(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new LinkedList<RequestHandle>()); 
requestMap.put(context, requestList); 
} 
} 
requestList.add(requestHandle); 
Iterator<RequestHandle> iterator = requestList.iterator(); 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while (iterator.hasNext()) { 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if (iterator.next().shouldBeGarbageCollected()) { 
iterator.remove(); 
} 
} 
} 
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return requestHandle; 
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li></ul>

这个方法的主要作用是将一个新的请求添加到队列线程池中执行。 

调用本方法,主要实现
AsyncHttpRequest request = newAsyncHttpRequest(client, httpContext, uriRequest,contentType, responseHandler, context);
这行开始是主要的逻辑,其创建了请求,接着通过
threadPool.submit(request);
把请求提交到线程池,接着通过
RequestHandle requestHandle = new RequestHandle(request);
把请求包装到RequestHandle用于之后的取消、管理等操作。然后坐等现在池的我们请求的这个线程去执行,等待返回结果。

总结一下:

AsyncHttpClient 核心类,使用HttpClient执行网络请求,提供了get,put,post,delete,head等请求方法,使用起来很简单,只需以url及RequestParams调用相应的方法即可,还可以选择性地传入Context,用于取消Content相关的请求,同时必须提供ResponseHandlerInterface(AsyncHttpResponseHandler继承自ResponseHandlerInterface)的实现类,一般为AsyncHttpResponseHandler的子类,AsyncHttpClient内部有一个线程池,当使用AsyncHttpClient执行网络请求时,最终都会调用sendRequest方法,在这个方法内部将请求参数封装成AsyncHttpRequest(继承自Runnable)交由内部的线程池执行。

SyncHttpClient 继承自AsyncHttpClient,同步执行网络请求,AsyncHttpClient把请求封装成AsyncHttpRequest后提交至线程池,SyncHttpClient把请求封装成AsyncHttpRequest后直接调用它的run方法。

AsyncHttpRequest 继承自Runnabler,被submit至线程池执行网络请求并发送start,success等消息。

AsyncHttpResponseHandler 接收请求结果,一般重写onSuccess及onFailure接收请求成功或失败的消息,还有onStart,onFinish等消息。

TextHttpResponseHandler、JsonHttpResponseHandler、BaseJsonHttpResponseHandler这些类都继承自AsyncHttpResponseHandler,只是重写了AsyncHttpResponseHandler的onSuccess和onFailure方法,将请求结果进行了转换而已。

RequestParams 请求参数,可以添加普通的字符串参数,并可添加File,InputStream上传文件。




原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/5843.html

(0)
上一篇 2021年7月17日
下一篇 2021年7月17日

相关推荐

发表回复

登录后才能评论