Android 开源框架之 Android-async-http 源码解读
開源項(xiàng)目鏈接
Android-async-http倉庫:https://github.com/loopj/android-async-http
android-async-http主頁:http://loopj.com/android-async-http/(估計(jì)需要翻墻)
開源項(xiàng)目簡介
該框架是基于Apache HttpClient API 用于Android開發(fā)的一個異步并發(fā)的網(wǎng)絡(luò)請求庫,所以的網(wǎng)絡(luò)請求都是在非UI線程中執(zhí)行,請求的結(jié)果都是通過接口回調(diào),利用Android的Handler+Message機(jī)制來從非UI線程中獲得。
開源框架的主要常用特征
1.支持HTTP網(wǎng)絡(luò)異步請求,通過接口回調(diào)獲得請求結(jié)果。 2.HTTP請求全部發(fā)生在非UI線程中。 3.使用線程池(ThreadPool)并發(fā)請求支援。 4.支持GET/POST 參數(shù)請求(RequestParams:封裝參數(shù)類)。 5.無需第三方lib,支持上傳文件。 6.支持網(wǎng)絡(luò)自動連接,網(wǎng)絡(luò)斷開重連機(jī)制。 7.支持關(guān)聯(lián)Activity生命周期取消網(wǎng)絡(luò)請求。開源框架使用實(shí)例
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
不過在一個完整的項(xiàng)目中官網(wǎng)不建議以上的使用方式,官網(wǎng)建議創(chuàng)建一個 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
這樣就免去了多次網(wǎng)絡(luò)請求創(chuàng)建多個HttpClient實(shí)例了。
帶參數(shù)的POST請求
該框架支持帶參數(shù)網(wǎng)絡(luò)請求,使用參數(shù)封裝類RequestParams。代碼示例: class TwitterRestClientUsage {//普通參數(shù)封裝RequestParams params = new RequestParams();params.put("key", "value");params.put("more", "data");//上傳文件參數(shù)封裝File myFile = new File("/path/to/file.png");RequestParams params = new RequestParams();try {params.put("profile_picture", myFile);} catch(FileNotFoundException e) {}//上傳流參數(shù)封裝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.從實(shí)例化對象開始 /*** Creates a new AsyncHttpClient with default constructor arguments values*/public AsyncHttpClient() {this(false, 80, 443);}/***所有的構(gòu)造方法最后都跳轉(zhuǎn)到這里,三個參數(shù)的含義如下* Creates new AsyncHttpClient using given params** @param fixNoHttpResponseException 是否添加SSL安全驗(yàn)證?默認(rèn)的是false* @param httpPort HTTP 端口,默認(rèn)80* @param httpsPort HTTPS 端口,默認(rèn)443*/public AsyncHttpClient(boolean fixNoHttpResponseException, int httpPort, int httpsPort) {this(getDefaultSchemeRegistry(fixNoHttpResponseException, httpPort, httpsPort));}/*** Creates a new AsyncHttpClient.* 這個構(gòu)造方法中配置網(wǎng)絡(luò)請求參數(shù),比如鏈接超時,最大連接數(shù),線程池創(chuàng)建,網(wǎng)絡(luò)重連機(jī)制等* @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");//執(zhí)行網(wǎng)絡(luò)請求的線程池,從代碼看,這是一個并發(fā)請求的線程池。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);//網(wǎng)絡(luò)出錯重連機(jī)制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
由源碼看出,所有的網(wǎng)絡(luò)請求都會跳轉(zhuǎn)到這個方法 sendRequest();,我們進(jìn)入代碼世界看看它里面都干了些啥?
protected RequestHandle sendRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, ResponseHandlerInterface responseHandler, Context context) {//代碼寫的很嚴(yán)謹(jǐn),判斷參數(shù)是否有效,值得學(xué)習(xí)。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());//創(chuàng)建一個異步網(wǎng)絡(luò)請求AsyncHttpRequest類實(shí)例,這個類繼承自Runnable,實(shí)現(xiàn)了run()方法。//方法里面是真正的網(wǎng)絡(luò)請求數(shù)據(jù)的過程,內(nèi)具怎么做呢?等下我們?nèi)タ纯础?/span>AsyncHttpRequest request = newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context);//重點(diǎn)啊,異步網(wǎng)絡(luò)請求線程被提交給線程池,讓線程池來實(shí)現(xiàn)網(wǎng)絡(luò)的并發(fā)請求。threadPool.submit(request);//網(wǎng)絡(luò)請求控制類,用于客戶端取消正在執(zhí)行的網(wǎng)絡(luò)請求。RequestHandle requestHandle = new RequestHandle(request);/**只有當(dāng)AsyncHttpClient與Activity關(guān)聯(lián)起來了才保存網(wǎng)絡(luò)請求requestHandle 用于客戶端控制網(wǎng)絡(luò)的請求*/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
真正執(zhí)行網(wǎng)絡(luò)請求的地方是 AsyncHttpRequest類,該類繼承自 Runnable接口,實(shí)現(xiàn)線程的run()方法。?
內(nèi)部具體怎么實(shí)現(xiàn)的,我們進(jìn)去看看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
- 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類,用來接收網(wǎng)絡(luò)請求的結(jié)果,一般重寫onSuccess及onFailure接收請求成功或失敗的消息,還有onStart,onFinish等消息。?
我們使用該框架的時候有一個參數(shù),那就是AsyncHttpResponseHandler了,比如:
- 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
就實(shí)現(xiàn)了AsyncHttpResponseHandler類的抽象方法。那么我們來看看這個類是怎么實(shí)現(xiàn)的??
在這里類里面,我們找到了這么一段代碼
- 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
這是一個內(nèi)部Handler類,實(shí)現(xiàn)了Handler+Message消息處理機(jī)制用來進(jìn)行子線程和UI線程通信。?
既然是Handler消息處理機(jī)制,那么我們看看在這個類中哪里使用了該內(nèi)部類發(fā)送消息??跟蹤代碼如下:
- 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()方法中調(diào)用了Handler的handler.sendMessage()方法。將異步任務(wù)結(jié)果發(fā)送給了UI線程。那到底哪里調(diào)用了這個方法呢? 繼續(xù)看代碼發(fā)現(xiàn):AsyncHttpResponseHandler類實(shí)現(xiàn)的接口方法
@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子線程中被回調(diào)的,因此這里的
sendMessage(obtainMessage(SUCCESS_MESSAGE, new Object[]{statusCode, headers, responseBytes}));- 1
- 1
是在子線程中執(zhí)行的,將回調(diào)的結(jié)果通過handler發(fā)送到UI線程中。
最后,所有的消息處理都跳轉(zhuǎn)到這個方法:
// 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
這里面調(diào)用了抽象方法 onSuccess和onFailure方法,讓客戶端去實(shí)現(xiàn)。至此,客戶端通過實(shí)現(xiàn)?
onSuccess和onFailure方法抽象方法來獲得網(wǎng)絡(luò)請求的結(jié)果。?
源碼分析大致如此。
開源框架總結(jié):
幾個關(guān)鍵的類:1.AsyncHttpRequest:繼承自Runnabler,被線程池submit執(zhí)行,用于真正執(zhí)行網(wǎng)絡(luò)異步請求的子線程。2.ResponseHandlerInterface:網(wǎng)絡(luò)請求接口回調(diào),用于將網(wǎng)絡(luò)請求結(jié)果通過接口的方式回調(diào)給UI線程。3.AsyncHttpResponseHandler:繼承自ResponseHandlerInterface,內(nèi)部實(shí)現(xiàn)了一個消息處理機(jī)制,用于將接口回調(diào)的網(wǎng)絡(luò)請求結(jié)果告訴UI線程。4.AsyncHttpClient:客戶端網(wǎng)絡(luò)請求核心類,使用HttpClient執(zhí)行網(wǎng)絡(luò)請求,提供了get,put,post,delete,head等請求方法,使用起來很簡單,只需以url及RequestParams調(diào)用相應(yīng)的方法即可,還可以選擇性地傳入Context,用于取消Content相關(guān)的請求,同時必須提供ResponseHandlerInterface(AsyncHttpResponseHandler繼承自ResponseHandlerInterface)的實(shí)現(xiàn)類,一般為AsyncHttpResponseHandler的子類,AsyncHttpClient內(nèi)部有一個線程池,當(dāng)使用AsyncHttpClient執(zhí)行網(wǎng)絡(luò)請求時,最終都會調(diào)用sendRequest方法,在這個方法內(nèi)部將請求參數(shù)封裝成AsyncHttpRequest(繼承自Runnable)交由內(nèi)部的線程池執(zhí)行。
框架請求流程
原文:http://blog.csdn.net/feiduclear_up/article/details/45370435
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Android 开源框架之 Android-async-http 源码解读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android安全系列工具
- 下一篇: android-async-http 源