日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 开源框架之 Android-async-http 源码解读

發布時間:2025/3/15 Android 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 开源框架之 Android-async-http 源码解读 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

開源項目鏈接

Android-async-http倉庫:https://github.com/loopj/android-async-http

android-async-http主頁:http://loopj.com/android-async-http/(估計需要翻墻)

開源項目簡介

該框架是基于Apache HttpClient API 用于Android開發的一個異步并發的網絡請求庫,所以的網絡請求都是在非UI線程中執行,請求的結果都是通過接口回調,利用Android的Handler+Message機制來從非UI線程中獲得。

開源框架的主要常用特征

1.支持HTTP網絡異步請求,通過接口回調獲得請求結果。 2.HTTP請求全部發生在非UI線程中。 3.使用線程池(ThreadPool)并發請求支援。 4.支持GET/POST 參數請求(RequestParams:封裝參數類)。 5.無需第三方lib,支持上傳文件。 6.支持網絡自動連接,網絡斷開重連機制。 7.支持關聯Activity生命周期取消網絡請求。

開源框架使用實例

AsyncHttpClient client = new AsyncHttpClient(); client.get("http://www.baidu.com", new AsyncHttpResponseHandler() {@Overridepublic void onStart() {// called before request is started}@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] response) {// called when response HTTP status is "200 OK"}@Overridepublic void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {// called when response HTTP status is "4XX" (eg. 401, 403, 404)}@Overridepublic void onRetry(int retryNo) {// called when request is retried} });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

不過在一個完整的項目中官網不建議以上的使用方式,官網建議創建一個 static 的 HttpClient,如下:

public class TwitterRestClient {private static final String BASE_URL = "http://api.twitter.com/1/";private static AsyncHttpClient client = new AsyncHttpClient();public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {client.get(getAbsoluteUrl(url), params, responseHandler);}public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {client.post(getAbsoluteUrl(url), params, responseHandler);}private static String getAbsoluteUrl(String relativeUrl) {return BASE_URL + relativeUrl;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

然后在客戶端很簡單的使用上面的方法,代碼如下:

class TwitterRestClientUsage {public void getPublicTimeline() throws JSONException {TwitterRestClient.get("statuses/public_timeline.json", null, new JsonHttpResponseHandler() {@Overridepublic void onSuccess(int statusCode, Header[] headers, JSONObject response) {// If the response is JSONObject instead of expected JSONArray}@Overridepublic void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {// Pull out the first event on the public timelineJSONObject firstEvent = timeline.get(0);String tweetText = firstEvent.getString("text");// Do something with the responseSystem.out.println(tweetText);}});} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

這樣就免去了多次網絡請求創建多個HttpClient實例了。

帶參數的POST請求

該框架支持帶參數網絡請求,使用參數封裝類RequestParams。代碼示例: class TwitterRestClientUsage {//普通參數封裝RequestParams params = new RequestParams();params.put("key", "value");params.put("more", "data");//上傳文件參數封裝File myFile = new File("/path/to/file.png");RequestParams params = new RequestParams();try {params.put("profile_picture", myFile);} catch(FileNotFoundException e) {}//上傳流參數封裝InputStream myInputStream = blah;RequestParams params = new RequestParams();params.put("secret_passwords", myInputStream, "passwords.txt");public void getPublicTimeline() throws JSONException {TwitterRestClient.post("statuses/public_timeline.json", params, new JsonHttpResponseHandler() {@Overridepublic void onSuccess(int statusCode, Header[] headers, JSONObject response) {// If the response is JSONObject instead of expected JSONArray}@Overridepublic void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {// Pull out the first event on the public timelineJSONObject firstEvent = timeline.get(0);String tweetText = firstEvent.getString("text");// Do something with the responseSystem.out.println(tweetText);}});} }
  • 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
  • 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

源碼解讀框架請求的原理

1.從實例化對象開始 /*** Creates a new AsyncHttpClient with default constructor arguments values*/public AsyncHttpClient() {this(false, 80, 443);}/***所有的構造方法最后都跳轉到這里,三個參數的含義如下* Creates new AsyncHttpClient using given params** @param fixNoHttpResponseException 是否添加SSL安全驗證?默認的是false* @param httpPort HTTP 端口,默認80* @param httpsPort HTTPS 端口,默認443*/public AsyncHttpClient(boolean fixNoHttpResponseException, int httpPort, int httpsPort) {this(getDefaultSchemeRegistry(fixNoHttpResponseException, httpPort, httpsPort));}/*** Creates a new AsyncHttpClient.* 這個構造方法中配置網絡請求參數,比如鏈接超時,最大連接數,線程池創建,網絡重連機制等* @param schemeRegistry SchemeRegistry to be used*/ public AsyncHttpClient(SchemeRegistry schemeRegistry) {BasicHttpParams httpParams = new BasicHttpParams();ConnManagerParams.setTimeout(httpParams, connectTimeout);ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(maxConnections));ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);HttpConnectionParams.setSoTimeout(httpParams, responseTimeout);HttpConnectionParams.setConnectionTimeout(httpParams, connectTimeout);HttpConnectionParams.setTcpNoDelay(httpParams, true);HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);ClientConnectionManager cm = createConnectionManager(schemeRegistry, httpParams);Utils.asserts(cm != null, "Custom implementation of #createConnectionManager(SchemeRegistry, BasicHttpParams) returned null");//執行網絡請求的線程池,從代碼看,這是一個并發請求的線程池。threadPool = getDefaultThreadPool();requestMap = Collections.synchronizedMap(new WeakHashMap<Context, List<RequestHandle>>());clientHeaderMap = new HashMap<String, String>();httpContext = new SyncBasicHttpContext(new BasicHttpContext());httpClient = new DefaultHttpClient(cm, httpParams);httpClient.addRequestInterceptor(new HttpRequestInterceptor() {@Overridepublic void process(HttpRequest request, HttpContext context) {if (!request.containsHeader(HEADER_ACCEPT_ENCODING)) {request.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);}for (String header : clientHeaderMap.keySet()) {if (request.containsHeader(header)) {Header overwritten = request.getFirstHeader(header);Log.d(LOG_TAG,String.format("Headers were overwritten! (%s | %s) overwrites (%s | %s)",header, clientHeaderMap.get(header),overwritten.getName(), overwritten.getValue()));//remove the overwritten headerrequest.removeHeader(overwritten);}request.addHeader(header, clientHeaderMap.get(header));}}});httpClient.addResponseInterceptor(new HttpResponseInterceptor() {@Overridepublic void process(HttpResponse response, HttpContext context) {final HttpEntity entity = response.getEntity();if (entity == null) {return;}final Header encoding = entity.getContentEncoding();if (encoding != null) {for (HeaderElement element : encoding.getElements()) {if (element.getName().equalsIgnoreCase(ENCODING_GZIP)) {response.setEntity(new InflatingEntity(entity));break;}}}}});httpClient.addRequestInterceptor(new HttpRequestInterceptor() {@Overridepublic void process(final HttpRequest request, final HttpContext context) 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);if (authState.getAuthScheme() == null) {AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());Credentials creds = credsProvider.getCredentials(authScope);if (creds != null) {authState.setAuthScheme(new BasicScheme());authState.setCredentials(creds);}}}}, 0);//網絡出錯重連機制httpClient.setHttpRequestRetryHandler(new RetryHandler(DEFAULT_MAX_RETRIES, DEFAULT_RETRY_SLEEP_TIME_MILLIS));}
  • 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
  • 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
2.GET/POST網絡請求

由源碼看出,所有的網絡請求都會跳轉到這個方法 sendRequest();,我們進入代碼世界看看它里面都干了些啥?

protected RequestHandle sendRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, ResponseHandlerInterface responseHandler, Context context) {//代碼寫的很嚴謹,判斷參數是否有效,值得學習。if (uriRequest == null) {throw new IllegalArgumentException("HttpUriRequest must not be null");}if (responseHandler == null) {throw new IllegalArgumentException("ResponseHandler must not be null");}if (responseHandler.getUseSynchronousMode() && !responseHandler.getUsePoolThread()) {throw new IllegalArgumentException("Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.");}if (contentType != null) {if (uriRequest instanceof HttpEntityEnclosingRequestBase && ((HttpEntityEnclosingRequestBase) uriRequest).getEntity() != null) {Log.w(LOG_TAG, "Passed contentType will be ignored because HttpEntity sets content type");} else {uriRequest.setHeader(HEADER_CONTENT_TYPE, contentType);}}responseHandler.setRequestHeaders(uriRequest.getAllHeaders());responseHandler.setRequestURI(uriRequest.getURI());//創建一個異步網絡請求AsyncHttpRequest類實例,這個類繼承自Runnable,實現了run()方法。//方法里面是真正的網絡請求數據的過程,內具怎么做呢?等下我們去看看。AsyncHttpRequest request = newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context);//重點啊,異步網絡請求線程被提交給線程池,讓線程池來實現網絡的并發請求。threadPool.submit(request);//網絡請求控制類,用于客戶端取消正在執行的網絡請求。RequestHandle requestHandle = new RequestHandle(request);/**只有當AsyncHttpClient與Activity關聯起來了才保存網絡請求requestHandle 用于客戶端控制網絡的請求*/if (context != null) {List<RequestHandle> requestList;// Add request to request mapsynchronized (requestMap) {requestList = requestMap.get(context);if (requestList == null) {requestList = Collections.synchronizedList(new LinkedList<RequestHandle>());requestMap.put(context, requestList);}}requestList.add(requestHandle);Iterator<RequestHandle> iterator = requestList.iterator();while (iterator.hasNext()) {if (iterator.next().shouldBeGarbageCollected()) {iterator.remove();}}}return requestHandle;}
  • 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
  • 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
3.AsyncHttpRequest的實現

真正執行網絡請求的地方是 AsyncHttpRequest類,該類繼承自 Runnable接口,實現線程的run()方法。?
內部具體怎么實現的,我們進去看看run()方法的代碼:

@Overridepublic void run() {if (isCancelled()) {return;}// Carry out pre-processing for this request only once.if (!isRequestPreProcessed) {isRequestPreProcessed = true;/**執行網絡請求前的準備操作,默認是個空方法,如果客戶需要在執行網絡請求前做一些準備工作,且很耗時的話,可以在外部重寫這個空方法。*/onPreProcessRequest(this);}if (isCancelled()) {return;}/*responseHandler :ResponseHandlerInterface接口的實例,用于接收網絡請求結果。具體實現等會一一分析。這里通過ResponseHandlerInterface接口回調告訴UI線程,網絡請求線程開始網絡請求了。*/responseHandler.sendStartMessage();if (isCancelled()) {return;}try {/**這里是真正執行網絡請求的入口。*/makeRequestWithRetries();} catch (IOException e) {if (!isCancelled()) {//如果網絡請求異常,將失敗結果通過ResponseHandlerInterface接口回調告訴UI線程。responseHandler.sendFailureMessage(0, null, null, e);} else {Log.e("AsyncHttpRequest", "makeRequestWithRetries returned error", e);}}if (isCancelled()) {return;}//這里通過ResponseHandlerInterface接口回調告訴UI線程,網絡請求線程結束網絡請求。responseHandler.sendFinishMessage();if (isCancelled()) {return;}// Carry out post-processing for this request.onPostProcessRequest(this);//標志網絡請求完成。isFinished = true;}.............................//真正的網絡請求,其中省略很多代碼,直接看重點就是makeRequest()方法了。private void makeRequestWithRetries() throws IOException {boolean retry = true;IOException cause = null;HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();try {.....................while (retry) {try {makeRequest();return;} ....................}private void makeRequest() throws IOException {...............................if (responseHandler instanceof RangeFileAsyncHttpResponseHandler) {((RangeFileAsyncHttpResponseHandler) responseHandler).updateRequestHeaders(request);}//終于到了,唉,是不是感覺有點熟悉,網絡請求獲得結果。HttpResponse response = client.execute(request, context);if (isCancelled()) {return;}// Carry out pre-processing for this response.responseHandler.onPreProcessResponse(responseHandler, response);if (isCancelled()) {return;}// The response is ready, handle it./**網絡請求通過ResponseHandlerInterface接口回調將請求的結果拿到。 那么到這里,我們是不是對ResponseHandlerInterface怎么將這些網絡請求結果告訴UI線程的呢??? 那么接下來,我們去分析下AsyncHttpResponseHandler類吧, 至于怎么就跳到這個類了呢?接下來看下面一點。*/responseHandler.sendResponseMessage(response);if (isCancelled()) {return;}// Carry out post-processing for this response.responseHandler.onPostProcessResponse(responseHandler, response);}
  • 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
  • 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

4.AsyncHttpResponseHandler類?
繼承自ResponseHandlerInterface類,用來接收網絡請求的結果,一般重寫onSuccess及onFailure接收請求成功或失敗的消息,還有onStart,onFinish等消息。?
我們使用該框架的時候有一個參數,那就是AsyncHttpResponseHandler了,比如:

AsyncHttpClient client = new AsyncHttpClient(); client.get("http://www.google.com", new AsyncHttpResponseHandler() { ..............@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] response) {// called when response HTTP status is "200 OK"}@Overridepublic void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {// called when response HTTP status is "4XX" (eg. 401, 403, 404)}.............. });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

就實現了AsyncHttpResponseHandler類的抽象方法。那么我們來看看這個類是怎么實現的??
在這里類里面,我們找到了這么一段代碼

/*** Avoid leaks by using a non-anonymous handler class.*/private static class ResponderHandler extends Handler {private final AsyncHttpResponseHandler mResponder;ResponderHandler(AsyncHttpResponseHandler mResponder, Looper looper) {super(looper);this.mResponder = mResponder;}@Overridepublic void handleMessage(Message msg) {mResponder.handleMessage(msg);}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

這是一個內部Handler類,實現了Handler+Message消息處理機制用來進行子線程和UI線程通信。?
既然是Handler消息處理機制,那么我們看看在這個類中哪里使用了該內部類發送消息??跟蹤代碼如下:

....................@Overridepublic void setUseSynchronousMode(boolean sync) {// A looper must be prepared before setting asynchronous mode.if (!sync && looper == null) {sync = true;Log.w(LOG_TAG, "Current thread has not called Looper.prepare(). Forcing synchronous mode.");}// If using asynchronous mode.if (!sync && handler == null) {// Create a handler on current thread to submit tasks//創建當前UI線程的Handler,用來發送異步任務結果給UI線程handler = new ResponderHandler(this, looper);} else if (sync && handler != null) {// TODO: Consider adding a flag to remove all queued messages.handler = null;}useSynchronousMode = sync;}...........................protected void sendMessage(Message msg) {if (getUseSynchronousMode() || handler == null) {handleMessage(msg);} else if (!Thread.currentThread().isInterrupted()) { /*do not send messages if request has been cancelled*/Utils.asserts(handler != null, "handler should not be null!");handler.sendMessage(msg);}}
  • 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
  • 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

在這個方法sendMessage()方法中調用了Handler的handler.sendMessage()方法。將異步任務結果發送給了UI線程。那到底哪里調用了這個方法呢? 繼續看代碼發現:AsyncHttpResponseHandler類實現的接口方法

@Overridefinal public void sendSuccessMessage(int statusCode, Header[] headers, byte[] responseBytes) {sendMessage(obtainMessage(SUCCESS_MESSAGE, new Object[]{statusCode, headers, responseBytes}));}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

這個接口是在AsyncHttpRequest子線程中被回調的,因此這里的

sendMessage(obtainMessage(SUCCESS_MESSAGE, new Object[]{statusCode, headers, responseBytes}));
  • 1
  • 1

是在子線程中執行的,將回調的結果通過handler發送到UI線程中。

最后,所有的消息處理都跳轉到這個方法:

// Methods which emulate android's Handler and Message methodsprotected void handleMessage(Message message) {Object[] response;try {switch (message.what) {case SUCCESS_MESSAGE:response = (Object[]) message.obj;if (response != null && response.length >= 3) {onSuccess((Integer) response[0], (Header[]) response[1], (byte[]) response[2]);} else {Log.e(LOG_TAG, "SUCCESS_MESSAGE didn't got enough params");}break;case FAILURE_MESSAGE:response = (Object[]) message.obj;if (response != null && response.length >= 4) {onFailure((Integer) response[0], (Header[]) response[1], (byte[]) response[2], (Throwable) response[3]);} else {Log.e(LOG_TAG, "FAILURE_MESSAGE didn't got enough params");}break;case START_MESSAGE:onStart();break;case FINISH_MESSAGE:onFinish();break;case PROGRESS_MESSAGE:response = (Object[]) message.obj;if (response != null && response.length >= 2) {try {onProgress((Integer) response[0], (Integer) response[1]);} catch (Throwable t) {Log.e(LOG_TAG, "custom onProgress contains an error", t);}} else {Log.e(LOG_TAG, "PROGRESS_MESSAGE didn't got enough params");}break;case RETRY_MESSAGE:response = (Object[]) message.obj;if (response != null && response.length == 1) {onRetry((Integer) response[0]);} else {Log.e(LOG_TAG, "RETRY_MESSAGE didn't get enough params");}break;case CANCEL_MESSAGE:onCancel();break;}} catch(Throwable error) {onUserException(error);}}
  • 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
  • 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

這里面調用了抽象方法 onSuccess和onFailure方法,讓客戶端去實現。至此,客戶端通過實現?
onSuccess和onFailure方法抽象方法來獲得網絡請求的結果。?
源碼分析大致如此。

開源框架總結:

幾個關鍵的類:1.AsyncHttpRequest:繼承自Runnabler,被線程池submit執行,用于真正執行網絡異步請求的子線程。2.ResponseHandlerInterface:網絡請求接口回調,用于將網絡請求結果通過接口的方式回調給UI線程。3.AsyncHttpResponseHandler:繼承自ResponseHandlerInterface,內部實現了一個消息處理機制,用于將接口回調的網絡請求結果告訴UI線程。4.AsyncHttpClient:

客戶端網絡請求核心類,使用HttpClient執行網絡請求,提供了get,put,post,delete,head等請求方法,使用起來很簡單,只需以url及RequestParams調用相應的方法即可,還可以選擇性地傳入Context,用于取消Content相關的請求,同時必須提供ResponseHandlerInterface(AsyncHttpResponseHandler繼承自ResponseHandlerInterface)的實現類,一般為AsyncHttpResponseHandler的子類,AsyncHttpClient內部有一個線程池,當使用AsyncHttpClient執行網絡請求時,最終都會調用sendRequest方法,在這個方法內部將請求參數封裝成AsyncHttpRequest(繼承自Runnable)交由內部的線程池執行。

框架請求流程

原文:http://blog.csdn.net/feiduclear_up/article/details/45370435

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的Android 开源框架之 Android-async-http 源码解读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。