日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Anroid-async-http封装网络请求框架源码分析

發布時間:2025/3/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Anroid-async-http封装网络请求框架源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ?Android-async-http開源項目可以是我們輕松的獲取網絡數據或者向服務器發送數據,使用起來非常簡單, 這個網絡請求庫是基于Apache HttpClient庫之上的一個異步網絡請求處理庫,網絡處理均基于Android的非UI線程,通過回調方法處理請求結果.

? ? ?主要特點:處理異步Http請求,并通過匿名內部類處理回調結果,Http異步請求均位于非UI線程,不會阻塞UI操作,通過線程池處理并發請求處理文件上傳、下載,響應結果自動打包JSON格式.

一,?Android-async-http的項目鏈接

? ? ? ?Github地址:https://github.com/loopj/android-async-http

? ? ?? V1.4.9的javadoc:? https://loopj.com/android-async-http/doc/

在DowloadZip下載zip包解壓后是Android Studio工程的目錄如下:

? ? ? ? ? ? ? ? ??

examples:里面有簡單的例子
library:里面存放的是android-async-http開源項目的源碼(方法一:可以把library\src\main\Java文件下面的文件拷貝到,你應用的src下也可以直接使用)
releases:里面存放的是各個版本的jar文件,(方法二:只需把最新的jar文件拷貝到你應用的libs目錄下即可.)
samples:里面存放的也是例子(可供參考)
備注:方法一和方法二只能采用其中之一,建議采用方法二

二,主要特性

1,Make asynchronous HTTP requests, handle responses in anonymous callbacks
? ? 異步http請求,匿名回調處理響應
2,HTTP requests happen outside the UI thread
? ? 在UI線程之外進行HTTP請求
3,Requests use a threadpool to cap concurrent resource usage
? ?請求使用線程池,限制使用資源并發情況
4,GET/POST params builder (RequestParams)
? ?使用RequestParams封裝GET/POST請求參數
5,Multipart file uploads with no additional third party libraries
? 不使用第三方庫多任務上傳
6,Tiny size overhead to your application, only 60kb for everything
? 占用應用的控件少只需要60kb
7,Automatic smart request retries optimized for spotty mobile connections
? 自動智能重試請求
8,Optional built-in response parsing into JSON (JsonHttpResponseHandler)
? ?內置響應解析成JSON,使用JsonHttpResponseHandler
9,Optional persistent cookie store, saves cookies into your app's SharedPreferences
? ?有選擇的持久化cookie存儲,保存在app的SharedPreferences文件

三,核心類介紹

對于http請求網絡的方式,無非就解決三個問題,第一,請求客戶端的方法,第二,請求參數的封裝,第三,請求響應的接收處理
先來看一下最基本的用法好有個大概的了解

AsyncHttpClient client = new AsyncHttpClient(); client.get("http://www.google.com", new AsyncHttpResponseHandler() {@Overridepublic void onSuccess(String response) {System.out.println(response);} }); 1,Http客戶端是誰?AsyncHttpClient

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

2,封裝的請求對象是誰?
? ? AsyncHttpRequest:繼承自Runnabler,被submit至線程池執行網絡請求并發送start,success等消息

3,請求參數和url怎么封裝?
? ??RequestParams:請求參數,可以添加普通的字符串參數,并可添加File,InputStream上傳文件,內部使用Map添加Key-Value


3,Http請求怎樣被執行?

? ? ?AsyncHttpClient對象執行get等方法,將Context,Url,RequestParams,responseHandler等參數傳入,在get()方法內部又封裝成sendRequest方法,sendRequest方法內又封裝請求AsyncHttpRequest,被提交到線程池的阻塞隊列,等待執行,AsyncHttpRequest實現了Runnable方法,線程執行run()方法,在run方法內,responseHandler可以調用sendStartMessage(),?makeRequestWithRetries(),sendFinishMessage()記錄任務執行的過程日志Log,在執行makeRequestWithRetries方法中執行真正的網絡執行語句HttpResponse response = client.execute(request, context);之后響應處理者調用sendResponseMessage(response),發送響應消息,最終轉到OnSuccess(int statusCode, Header[] headers, byte[] responseBody);響應處理者子類只需要重寫這個方法,對返回的響應做響應的處理


4,請求響應用什么方式處理?AsyncHttpResponseHandler, TextHttpResponseHandler, JsonHttpResponseHandler, BaseJsonHttpResponseHandler

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?繼承圖

? ? ? ? ? ??
AsyncHttpResponseHandler:

? ? ? 接收請求結果,一般重寫onSuccess及onFailure接收請求成功或失敗的消息,還有onStart,onFinish等消息

//這個方法是子類必須重寫的方法,來處理響應的public abstract void onSuccess(int statusCode, Header[] headers, byte[] responseBody);/*** Fired when a request fails to complete, override to handle in your own code** @param statusCode return HTTP status code* @param headers return headers, if any* @param responseBody the response body, if any* @param error the underlying cause of the failure*///這個方法是子類必須重寫的方法,來處理響應的public abstract void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error);
BinaryHttpResponseHandler extends AsyncHttpResponseHandler :

? ? ? ? 繼承AsyncHttpResponseHandler的子類,這是一個字節流返回處理的類, 該類用于處理圖片,流的形式;

@Overridepublic abstract void onSuccess(int statusCode, Header[] headers, byte[] binaryData);@Overridepublic abstract void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error);
TextHttpResponseHandler:

? ? ? ?繼承自AsyncHttpResponseHandler,只是重寫了AsyncHttpResponseHandler的onSuccess和onFailure方法,將請求結果由byte數組轉換為String

/*** Called when request fails** @param statusCode http response status line* @param headers response headers if any* @param responseString string response of given charset* @param throwable throwable returned when processing request*/public abstract void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable);/*** Called when request succeeds** @param statusCode http response status line* @param headers response headers if any* @param responseString string response of given charset*/public abstract void onSuccess(int statusCode, Header[] headers, String responseString);
JsonHttpResponseHandler:

? ? ? ?繼承自TextHttpResponseHandler,是一個泛型類,提供了parseResponse方法,子類需要提供實現,將請求結果解析成需要的類型,子類可以靈活地使用解析方法,可以直接原始解析,使用gson等。

/*** Returns when request succeeds** @param statusCode http response status line* @param headers response headers if any* @param response parsed response if any*/public void onSuccess(int statusCode, Header[] headers, JSONObject response) {AsyncHttpClient.log.w(LOG_TAG, "onSuccess(int, Header[], JSONObject) was not overriden, but callback was received");}/*** Returns when request succeeds** @param statusCode http response status line* @param headers response headers if any* @param response parsed response if any*/public void onSuccess(int statusCode, Header[] headers, JSONArray response) {AsyncHttpClient.log.w(LOG_TAG, "onSuccess(int, Header[], JSONArray) was not overriden, but callback was received");}/*** Returns when request failed** @param statusCode http response status line* @param headers response headers if any* @param throwable throwable describing the way request failed* @param errorResponse parsed response if any*/public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {AsyncHttpClient.log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONObject) was not overriden, but callback was received", throwable);}/*** Returns when request failed** @param statusCode http response status line* @param headers response headers if any* @param throwable throwable describing the way request failed* @param errorResponse parsed response if any*/public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {AsyncHttpClient.log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONArray) was not overriden, but callback was received", throwable);}@Overridepublic void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {AsyncHttpClient.log.w(LOG_TAG, "onFailure(int, Header[], String, Throwable) was not overriden, but callback was received", throwable);}@Overridepublic void onSuccess(int statusCode, Header[] headers, String responseString) {AsyncHttpClient.log.w(LOG_TAG, "onSuccess(int, Header[], String) was not overriden, but callback was received");} /*** Returns Object of type {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long,* Double or {@link JSONObject#NULL}, see {@link org.json.JSONTokener#nextValue()}** @param responseBody response bytes to be assembled in String and parsed as JSON* @return Object parsedResponse* @throws org.json.JSONException exception if thrown while parsing JSON*/protected Object parseResponse(byte[] responseBody) throws JSONException {if (null == responseBody)return null;Object result = null;//trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If JSON is not valid this will return nullString jsonString = getResponseString(responseBody, getCharset());if (jsonString != null) {jsonString = jsonString.trim();if (useRFC5179CompatibilityMode) {if (jsonString.startsWith("{") || jsonString.startsWith("[")) {result = new JSONTokener(jsonString).nextValue();}} else {// Check if the string is an JSONObject style {} or JSONArray style []// If not we consider this as a stringif ((jsonString.startsWith("{") && jsonString.endsWith("}"))|| jsonString.startsWith("[") && jsonString.endsWith("]")) {result = new JSONTokener(jsonString).nextValue();}// Check if this is a String "my String value" and remove quote// Other value type (numerical, boolean) should be without quoteelse if (jsonString.startsWith("\"") && jsonString.endsWith("\"")) {result = jsonString.substring(1, jsonString.length() - 1);}}}if (result == null) {result = jsonString;}return result;}
四,原理流程圖


1,調用AsyncHttpClient的get或post等方法發起網絡請求
2,所有的請求都走了sendRequest,在sendRequest中把請求封裝為
AsyncHttpRequest,并添加到線程池執行,

3,請求被執行時(即AsyncHttpRequest的run方法),執行AsyncHttpRequest的makeRequestWithRetries方法執行實際的請求,當請求失敗時可以重試。并在請求開始,結束,成功或失敗時向請求時傳的ResponseHandlerInterface實例發送消息

4,基本上使用的都是AsyncHttpResponseHandler的子類,調用其onStart,onSuccess等方法返回請求結果

五,核心源碼解讀

1,AsyncHttpClient.java

以Get方法為例分析源碼: /*** Perform a HTTP GET request, without any parameters.* 執行一個沒有參數的HTTP Get請求* @param url the URL to send the request to. 請求Url* @param responseHandler the response handler instance that should handle the response.處理響應對象* @return RequestHandle of future request process*/public RequestHandle get(String url, ResponseHandlerInterface responseHandler) {return get(null, url, null, responseHandler);//轉到另一個重載函數,四個參數是Context,Url,RequestParams,ResponseHandler}// [-] HTTP GET// [+] HTTP POST/*** Perform a HTTP GET request with parameters.*執行一個有參數的HTTP Get請求* @param url the URL to send the request to.* @param params additional GET parameters to send with the request.* @param responseHandler the response handler instance that should handle the response.* @return RequestHandle of future request process*/public RequestHandle get(String url, RequestParams params, ResponseHandlerInterface responseHandler) {return get(null, url, params, responseHandler);//轉到另一個重載函數,四個參數是Context,Url,RequestParams,ResponseHandler}/*** Perform a HTTP GET request without any parameters and track the Android Context which* initiated the request.** @param context the Android Context which initiated the request.* @param url the URL to send the request to.* @param responseHandler the response handler instance that should handle the response.* @return RequestHandle of future request process*/public RequestHandle get(Context context, String url, ResponseHandlerInterface responseHandler) {return get(context, url, null, responseHandler);}/*** Perform a HTTP GET request and track the Android Context which initiated the request.*執行一個Http Get請求,有Context參數,初始化request* @param context the Android Context which initiated the request. // android上下文context* @param url the URL to send the request to.//請去的url* @param params additional GET parameters to send with the request.//請求的參數* @param responseHandler the response handler instance that should handle the response.//處理響應對象* @return RequestHandle of future request process*/public RequestHandle get(Context context, String url, RequestParams params, ResponseHandlerInterface responseHandler) {/** 封裝sendRequest的方法,感覺和HttpClient的方式相似,不是很懂,參數如下*1,DefaultHttpClient httpClient*2,HttpContext httpContext*3,HttpGet httpget*4,*5,ResponseHandlerInterface responseHandler*6,Context context*/return sendRequest(httpClient, httpContext, new HttpGet(getUrlWithQueryString(isUrlEncodingEnabled, url, params)), null, responseHandler, context);}/*** Perform a HTTP GET request and track the Android Context which initiated the request with* customized headers* 執行有自定義Header的請求* @param context Context to execute request against* @param url the URL to send the request to.* @param headers set headers only for this request* @param params additional GET parameters to send with the request.* @param responseHandler the response handler instance that should handle the response.* @return RequestHandle of future request process*/public RequestHandle get(Context context, String url, Header[] headers, RequestParams params, ResponseHandlerInterface responseHandler) {HttpUriRequest request = new HttpGet(getUrlWithQueryString(isUrlEncodingEnabled, url, params));if (headers != null) request.setHeaders(headers);//自定義的Header加入到,HttpGet對象中return sendRequest(httpClient, httpContext, request, null, responseHandler,context);}/*** Puts a new request in queue as a new thread in pool to be executed* 把一個新的請求放入線程池的隊列被執行* @param client HttpClient to be used for request, can differ in single requests* @param contentType MIME body type, for POST and PUT requests, may be null* @param context Context of Android application, to hold the reference of request* @param httpContext HttpContext in which the request will be executed* @param responseHandler ResponseHandler or its subclass to put the response into* @param uriRequest instance of HttpUriRequest, which means it must be of HttpDelete,* HttpPost, HttpGet, HttpPut, etc.* @return RequestHandle of future request process*/ /** 封裝sendRequest的方法,感覺和HttpClient的方式相似,不是很懂,參數如下*1,DefaultHttpClient httpClient*2,HttpContext httpContext*3,HttpGet httpget*4,String contentType,*5,ResponseHandlerInterface responseHandler*6,Context context*/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 && uriRequest.containsHeader(HEADER_CONTENT_TYPE)) {log.w(LOG_TAG, "Passed contentType will be ignored because HttpEntity sets content type");} else {uriRequest.setHeader(HEADER_CONTENT_TYPE, contentType);}}//responseHandler設置請求頭和請去UrlresponseHandler.setRequestHeaders(uriRequest.getAllHeaders());responseHandler.setRequestURI(uriRequest.getURI());//構造一個執行請求的AsyncHttpRequest對象,準備被發送到線程池的任務隊列,等待執行AsyncHttpRequest對象中的run方法AsyncHttpRequest request = newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context);threadPool.submit(request);//重點!!!!: 把AsyncHttpRequest對象提交到線程池等待執行/*** A Handle to an AsyncRequest which can be used to cancel a running request.* 一個可以用來取消正在運行的請求的手柄或者說是操作者*/RequestHandle requestHandle = new RequestHandle(request);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;//返回手柄} AsyncHttpRequest.java

/*** Internal class, representing the HttpRequest, done in asynchronous manner*///異步HTTP請求對象,實現的是Runnable接口,說明AsyncHttpRequest是一個供線程執行的任務類,主要關注run方法 public class AsyncHttpRequest implements Runnable {private final AbstractHttpClient client;//Http客戶端,Httpclientprivate final HttpContext context;private final HttpUriRequest request;//保存HttpGet對象private final ResponseHandlerInterface responseHandler;//保存響應處理者對象,可以跟蹤任務的執行,start,fihish等private final AtomicBoolean isCancelled = new AtomicBoolean();private int executionCount;private boolean cancelIsNotified;private volatile boolean isFinished;private boolean isRequestPreProcessed;public AsyncHttpRequest(AbstractHttpClient client, HttpContext context, HttpUriRequest request, ResponseHandlerInterface responseHandler) {this.client = Utils.notNull(client, "client");this.context = Utils.notNull(context, "context");this.request = Utils.notNull(request, "request");this.responseHandler = Utils.notNull(responseHandler, "responseHandler");}/*** This method is called once by the system when the request is about to be* processed by the system. The library makes sure that a single request* is pre-processed only once.* <p>?</p>* Please note: pre-processing does NOT run on the main thread, and thus* any UI activities that you must perform should be properly dispatched to* the app's UI thread.** @param request The request to pre-process*/public void onPreProcessRequest(AsyncHttpRequest request) {// default action is to do nothing...}/*** This method is called once by the system when the request has been fully* sent, handled and finished. The library makes sure that a single request* is post-processed only once.* <p>?</p>* Please note: post-processing does NOT run on the main thread, and thus* any UI activities that you must perform should be properly dispatched to* the app's UI thread.** @param request The request to post-process*/public void onPostProcessRequest(AsyncHttpRequest request) {// default action is to do nothing...}/** 在線程池中執行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發送開始消息,響應處理者設置start消息responseHandler.sendStartMessage();if (isCancelled()) {return;}try {//重點是這個方法!!!makeRequestWithRetries();} catch (IOException e) {if (!isCancelled()) {//任務執行失敗,響應處理者設置failure消息responseHandler.sendFailureMessage(0, null, null, e);} else {AsyncHttpClient.log.e("AsyncHttpRequest", "makeRequestWithRetries returned error", e);}}if (isCancelled()) {return;}//任務執行完成,響應處理者設置finish消息responseHandler.sendFinishMessage();if (isCancelled()) {return;}// Carry out post-processing for this request.//任務執行完畢,調用這個方法onPostProcessRequest(this);isFinished = true;}//makeRequestprivate void makeRequest() throws IOException {if (isCancelled()) {return;}// Fixes #115if (request.getURI().getScheme() == null) {// subclass of IOException so processed in the callerthrow new MalformedURLException("No valid URI scheme was provided");}if (responseHandler instanceof RangeFileAsyncHttpResponseHandler) {((RangeFileAsyncHttpResponseHandler) responseHandler).updateRequestHeaders(request);}//終于看到這一句了,感覺就是我們常用的HttpClient,HttpGet,HttpResponse模式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.//猜到就是把HttpResponse對象封裝到響應處理者responseHandler中,responseHandler中肯定有保存HttpResponse對象的變量responseHandler.sendResponseMessage(response);if (isCancelled()) {return;}// Carry out post-processing for this response.//返回響應之后的后處理,一個請求就這么處理完了,接下來只需要出去處理responseHandler就可以得到響應了responseHandler.onPostProcessResponse(responseHandler, response);}//重點是這個方法!!!做請求帶有重試次數的private void makeRequestWithRetries() throws IOException {boolean retry = true;IOException cause = null;HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();try {while (retry) {try {//重點是去makerequestmakeRequest();return;} catch (UnknownHostException e) {// switching between WI-FI and mobile data networks can cause a retry which then results in an UnknownHostException// while the WI-FI is initialising. The retry logic will be invoked here, if this is NOT the first retry// (to assist in genuine cases of unknown host) which seems better than outright failurecause = new IOException("UnknownHostException exception: " + e.getMessage(), e);//如果執行拋出異常,會重試連接,可能是這樣理解的retry = (executionCount > 0) && retryHandler.retryRequest(e, ++executionCount, context);} catch (NullPointerException e) {// there's a bug in HttpClient 4.0.x that on some occasions causes// DefaultRequestExecutor to throw an NPE, see// https://code.google.com/p/android/issues/detail?id=5255cause = new IOException("NPE in HttpClient: " + e.getMessage());retry = retryHandler.retryRequest(cause, ++executionCount, context);} catch (IOException e) {if (isCancelled()) {// Eating exception, as the request was cancelledreturn;}cause = e;retry = retryHandler.retryRequest(cause, ++executionCount, context);}if (retry) {responseHandler.sendRetryMessage(executionCount);}}} catch (Exception e) {// catch anything else to ensure failure message is propagatedAsyncHttpClient.log.e("AsyncHttpRequest", "Unhandled exception origin cause", e);cause = new IOException("Unhandled exception: " + e.getMessage(), cause);}// cleaned up to throw IOExceptionthrow (cause);}AsyncHttpResponseHandler.java

/*** Fired when the request is started, override to handle in your own code*//*asyncHttpRequst的run方法執行時調用sendStartMessage發送開始消息* 其實就是轉入這個OnStart函數,如果想跟蹤任務執行的話寫log就重寫這個方法*/public void onStart() {// default log warning is not necessary, because this method is just optional notification}/*** Fired in all cases when the request is finished, after both success and failure, override to* handle in your own code*//*asyncHttpRequst的run方法執行時調用sendFinishMessage發送開始消息* 其實就是轉入這個onFinish函數,如果想跟蹤任務執行的話寫log就重寫這個方法*/public void onFinish() {// default log warning is not necessary, because this method is just optional notification}/**asyncHttpRequst的run方法執行到makeRequest方法時,執行完畢會調用一下兩個函數*onPreProcessResponse 是指在返回響應之前的預處理*onPostProcessResponse 是指返回響應之后的處理*/@Overridepublic void onPreProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {// default action is to do nothing...}@Overridepublic void onPostProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {// default action is to do nothing...}/*** Fired when a request returns successfully, override to handle in your own code** @param statusCode the status code of the response 響應的響應碼* @param headers return headers, if any 響應的Header頭信息* @param responseBody the body of the HTTP response from the server 響應體*///這個方法是子類必須重寫的方法,來處理響應的public abstract void onSuccess(int statusCode, Header[] headers, byte[] responseBody);/*** Fired when a request fails to complete, override to handle in your own code** @param statusCode return HTTP status code* @param headers return headers, if any* @param responseBody the response body, if any* @param error the underlying cause of the failure*///這個方法是子類必須重寫的方法,來處理響應的public abstract void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error); // 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方法onSuccess((Integer) response[0], (Header[]) response[1], (byte[]) response[2]);} else {AsyncHttpClient.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方法onFailure((Integer) response[0], (Header[]) response[1], (byte[]) response[2], (Throwable) response[3]);} else {AsyncHttpClient.log.e(LOG_TAG, "FAILURE_MESSAGE didn't got enough params");}break;case START_MESSAGE://調用onStart方法onStart();break;case FINISH_MESSAGE://調用onFinish方法onFinish();break;case PROGRESS_MESSAGE:response = (Object[]) message.obj;if (response != null && response.length >= 2) {try {onProgress((Long) response[0], (Long) response[1]);} catch (Throwable t) {AsyncHttpClient.log.e(LOG_TAG, "custom onProgress contains an error", t);}} else {AsyncHttpClient.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 {AsyncHttpClient.log.e(LOG_TAG, "RETRY_MESSAGE didn't get enough params");}break;case CANCEL_MESSAGE://調用onFinish方法onCancel();break;}} catch (Throwable error) {onUserException(error);}} }/*asyncHttpRequst的run方法執行到makeRequest方法時,獲得HttpResponse后會調用如下方法sendResponseMessage****/@Overridepublic void sendResponseMessage(HttpResponse response) throws IOException {// do not process if request has been cancelled//因為asyncHttpRequst在線程池中執行,先判斷線程if (!Thread.currentThread().isInterrupted()) {//獲取狀態行StatusLine status = response.getStatusLine();byte[] responseBody;//獲取響應體的字節數組responseBody = getResponseData(response.getEntity());// additional cancellation check as getResponseData() can take non-zero time to processif (!Thread.currentThread().isInterrupted()) {if (status.getStatusCode() >= 300) {//如果響應碼大于等于300,則發送失敗消息,失敗和成功消息是判斷響應碼發生的,開始和結束消息是任務執行發生的sendFailureMessage(status.getStatusCode(), response.getAllHeaders(), responseBody, new HttpResponseException(status.getStatusCode(), status.getReasonPhrase()));} else {//否則發送成功消息,參數是響應碼,響應頭信息,響應體sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(), responseBody);}}}} AsyncRequestParams.java

public class RequestParams implements Serializable {public final static String APPLICATION_OCTET_STREAM ="application/octet-stream";public final static String APPLICATION_JSON ="application/json";protected final static String LOG_TAG = "RequestParams";//d都是用的是并發HashMap,Url的參數protected final ConcurrentHashMap<String, String> urlParams = new ConcurrentHashMap<String, String>();//各種流的參數HashMapprotected final ConcurrentHashMap<String, StreamWrapper> streamParams = new ConcurrentHashMap<String, StreamWrapper>();//各種文件的參數HashMapprotected final ConcurrentHashMap<String, FileWrapper> fileParams = new ConcurrentHashMap<String, FileWrapper>();//多文件的參數HashMapprotected final ConcurrentHashMap<String, List<FileWrapper>> fileArrayParams = new ConcurrentHashMap<String, List<FileWrapper>>();//帶對象的Url的參數HashMapprotected final ConcurrentHashMap<String, Object> urlParamsWithObjects = new ConcurrentHashMap<String, Object>();protected boolean isRepeatable;protected boolean forceMultipartEntity = false;protected boolean useJsonStreamer;protected String elapsedFieldInJsonStreamer = "_elapsed";protected boolean autoCloseInputStreams;protected String contentEncoding = HTTP.UTF_8;/*** Constructs a new empty {@code RequestParams} instance.*/public RequestParams() {this((Map<String, String>) null);}/*** Constructs a new RequestParams instance containing the key/value string params from the* specified map.** @param source the source key/value string map to add.*/public RequestParams(Map<String, String> source) {if (source != null) {for (Map.Entry<String, String> entry : source.entrySet()) {put(entry.getKey(), entry.getValue());}}}/*** Constructs a new RequestParams instance and populate it with a single initial key/value* string param.** @param key the key name for the intial param.* @param value the value string for the initial param.*/public RequestParams(final String key, final String value) {this(new HashMap<String, String>() {{put(key, value);}});}/*** Constructs a new RequestParams instance and populate it with multiple initial key/value* string param.** @param keysAndValues a sequence of keys and values. Objects are automatically converted to* Strings (including the value {@code null}).* @throws IllegalArgumentException if the number of arguments isn't even.*/public RequestParams(Object... keysAndValues) {int len = keysAndValues.length;if (len % 2 != 0)throw new IllegalArgumentException("Supplied arguments must be even");for (int i = 0; i < len; i += 2) {String key = String.valueOf(keysAndValues[i]);String val = String.valueOf(keysAndValues[i + 1]);put(key, val);}}/*** Sets content encoding for return value of {@link #getParamString()} and {@link* #createFormEntity()} <p>?</p> Default encoding is "UTF-8"** @param encoding String constant from {@link HTTP}*/public void setContentEncoding(final String encoding) {if (encoding != null) {this.contentEncoding = encoding;} else {AsyncHttpClient.log.d(LOG_TAG, "setContentEncoding called with null attribute");}}/*** If set to true will force Content-Type header to `multipart/form-data`* even if there are not Files or Streams to be send* <p>?</p>* Default value is false** @param force boolean, should declare content-type multipart/form-data even without files or streams present*/public void setForceMultipartEntityContentType(boolean force) {this.forceMultipartEntity = force;}/*** Adds a key/value string pair to the request.** @param key the key name for the new param.* @param value the value string for the new param.*/public void put(String key, String value) {if (key != null && value != null) {urlParams.put(key, value);}}/*** Adds files array to the request.** @param key the key name for the new param.* @param files the files array to add.* @throws FileNotFoundException if one of passed files is not found at time of assembling the requestparams into request*/public void put(String key, File files[]) throws FileNotFoundException {put(key, files, null, null);}/*** Adds files array to the request with both custom provided file content-type and files name** @param key the key name for the new param.* @param files the files array to add.* @param contentType the content type of the file, eg. application/json* @param customFileName file name to use instead of real file name* @throws FileNotFoundException throws if wrong File argument was passed*/public void put(String key, File files[], String contentType, String customFileName) throws FileNotFoundException {if (key != null) {List<FileWrapper> fileWrappers = new ArrayList<FileWrapper>();for (File file : files) {if (file == null || !file.exists()) {throw new FileNotFoundException();}fileWrappers.add(new FileWrapper(file, contentType, customFileName));}fileArrayParams.put(key, fileWrappers);}}/*** Adds a file to the request.** @param key the key name for the new param.* @param file the file to add.* @throws FileNotFoundException throws if wrong File argument was passed*/public void put(String key, File file) throws FileNotFoundException {put(key, file, null, null);}/*** Adds a file to the request with custom provided file name** @param key the key name for the new param.* @param file the file to add.* @param customFileName file name to use instead of real file name* @throws FileNotFoundException throws if wrong File argument was passed*/public void put(String key, String customFileName, File file) throws FileNotFoundException {put(key, file, null, customFileName);}/*** Adds a file to the request with custom provided file content-type** @param key the key name for the new param.* @param file the file to add.* @param contentType the content type of the file, eg. application/json* @throws FileNotFoundException throws if wrong File argument was passed*/public void put(String key, File file, String contentType) throws FileNotFoundException {put(key, file, contentType, null);}/*** Adds a file to the request with both custom provided file content-type and file name** @param key the key name for the new param.* @param file the file to add.* @param contentType the content type of the file, eg. application/json* @param customFileName file name to use instead of real file name* @throws FileNotFoundException throws if wrong File argument was passed*/public void put(String key, File file, String contentType, String customFileName) throws FileNotFoundException {if (file == null || !file.exists()) {throw new FileNotFoundException();}if (key != null) {fileParams.put(key, new FileWrapper(file, contentType, customFileName));}}/*** Adds an input stream to the request.** @param key the key name for the new param.* @param stream the input stream to add.*/public void put(String key, InputStream stream) {put(key, stream, null);}/*** Adds an input stream to the request.** @param key the key name for the new param.* @param stream the input stream to add.* @param name the name of the stream.*/public void put(String key, InputStream stream, String name) {put(key, stream, name, null);}/*** Adds an input stream to the request.** @param key the key name for the new param.* @param stream the input stream to add.* @param name the name of the stream.* @param contentType the content type of the file, eg. application/json*/public void put(String key, InputStream stream, String name, String contentType) {put(key, stream, name, contentType, autoCloseInputStreams);}/*** Adds an input stream to the request.** @param key the key name for the new param.* @param stream the input stream to add.* @param name the name of the stream.* @param contentType the content type of the file, eg. application/json* @param autoClose close input stream automatically on successful upload*/public void put(String key, InputStream stream, String name, String contentType, boolean autoClose) {if (key != null && stream != null) {streamParams.put(key, StreamWrapper.newInstance(stream, name, contentType, autoClose));}}/*** Adds param with non-string value (e.g. Map, List, Set).** @param key the key name for the new param.* @param value the non-string value object for the new param.*/public void put(String key, Object value) {if (key != null && value != null) {urlParamsWithObjects.put(key, value);}}/*** Adds a int value to the request.** @param key the key name for the new param.* @param value the value int for the new param.*/public void put(String key, int value) {if (key != null) {urlParams.put(key, String.valueOf(value));}}/*** Adds a long value to the request.** @param key the key name for the new param.* @param value the value long for the new param.*/public void put(String key, long value) {if (key != null) {urlParams.put(key, String.valueOf(value));}}/*** Adds string value to param which can have more than one value.** @param key the key name for the param, either existing or new.* @param value the value string for the new param.*/public void add(String key, String value) {if (key != null && value != null) {Object params = urlParamsWithObjects.get(key);if (params == null) {// Backward compatible, which will result in "k=v1&k=v2&k=v3"params = new HashSet<String>();this.put(key, params);}if (params instanceof List) {((List<Object>) params).add(value);} else if (params instanceof Set) {((Set<Object>) params).add(value);}}}/*** Removes a parameter from the request.** @param key the key name for the parameter to remove.*/public void remove(String key) {urlParams.remove(key);streamParams.remove(key);fileParams.remove(key);urlParamsWithObjects.remove(key);fileArrayParams.remove(key);}/*** Check if a parameter is defined.** @param key the key name for the parameter to check existence.* @return Boolean*/public boolean has(String key) {return urlParams.get(key) != null ||streamParams.get(key) != null ||fileParams.get(key) != null ||urlParamsWithObjects.get(key) != null ||fileArrayParams.get(key) != null;}//在AsyncHttpRequest執行中會調用這個方法//其實轉化成了key1=value1&key2=value2的字符串@Overridepublic String toString() {StringBuilder result = new StringBuilder();for (ConcurrentHashMap.Entry<String, String> entry : urlParams.entrySet()) {if (result.length() > 0)result.append("&");result.append(entry.getKey());result.append("=");result.append(entry.getValue());}for (ConcurrentHashMap.Entry<String, StreamWrapper> entry : streamParams.entrySet()) {if (result.length() > 0)result.append("&");result.append(entry.getKey());result.append("=");result.append("STREAM");}for (ConcurrentHashMap.Entry<String, FileWrapper> entry : fileParams.entrySet()) {if (result.length() > 0)result.append("&");result.append(entry.getKey());result.append("=");result.append("FILE");}for (ConcurrentHashMap.Entry<String, List<FileWrapper>> entry : fileArrayParams.entrySet()) {if (result.length() > 0)result.append("&");result.append(entry.getKey());result.append("=");result.append("FILES(SIZE=").append(entry.getValue().size()).append(")");}List<BasicNameValuePair> params = getParamsList(null, urlParamsWithObjects);for (BasicNameValuePair kv : params) {if (result.length() > 0)result.append("&");result.append(kv.getName());result.append("=");result.append(kv.getValue());}return result.toString();}
六,使用方法

官方建議:Recommended Usage: Make a Static Http Client

import com.loopj.android.http.*;public class TwitterRestClient {private static final String BASE_URL = "https://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;} } AsyncRequestParams.java'

RequestParams params = new RequestParams(); params.put("username", "yanbober"); params.put("password", "123456"); params.put("email", "yanbobersky@email.com");/* * Upload a File */ params.put("file_pic", new File("test.jpg")); params.put("file_inputStream", inputStream); params.put("file_bytes", new ByteArrayInputStream(bytes));/* * url params: "user[first_name]=jesse&user[last_name]=yan" */ Map<String, String> map = new HashMap<String, String>(); map.put("first_name", "jesse"); map.put("last_name", "yan"); params.put("user", map);/* * url params: "what=haha&like=wowo" */ Set<String> set = new HashSet<String>(); set.add("haha"); set.add("wowo"); params.put("what", set);/* * url params: "languages[]=Java&languages[]=C" */ List<String> list = new ArrayList<String>(); list.add("Java"); list.add("C"); params.put("languages", list);/* * url params: "colors[]=blue&colors[]=yellow" */ String[] colors = { "blue", "yellow" }; params.put("colors", colors);/* * url params: "users[][age]=30&users[][gender]=male&users[][age]=25&users[][gender]=female" */ List<Map<String, String>> listOfMaps = new ArrayList<Map<String, String>>(); Map<String, String> user1 = new HashMap<String, String>(); user1.put("age", "30"); user1.put("gender", "male");Map<String, String> user2 = new HashMap<String, String>(); user2.put("age", "25"); user2.put("gender", "female");listOfMaps.add(user1); listOfMaps.add(user2);params.put("users", listOfMaps);/* * 使用實例 */ AsyncHttpClient client = new AsyncHttpClient(); client.post("http://localhost:8080/androidtest/", params, responseHandler)JsonHttpResponseHandler帶Json參數的POST:
try {JSONObject jsonObject = new JSONObject();jsonObject.put("username", "ryantang");StringEntity stringEntity = new StringEntity(jsonObject.toString());client.post(mContext, "http://api.com/login", stringEntity, "application/json", new JsonHttpResponseHandler(){@Overridepublic void onSuccess(JSONObject jsonObject) {super.onSuccess(jsonObject);}}); } catch (JSONException e) {e.printStackTrace(); } catch (UnsupportedEncodingException e) {e.printStackTrace(); }BinaryHttpResponseHandler下載文件:

client.get("http://download/file/test.java", new BinaryHttpResponseHandler() {@Overridepublic void onSuccess(byte[] arg0) {super.onSuccess(arg0);File file = Environment.getExternalStorageDirectory();File file2 = new File(file, "down");file2.mkdir();file2 = new File(file2, "down_file.jpg");try {FileOutputStream oStream = new FileOutputStream(file2);oStream.write(arg0);oStream.flush();oStream.close();} catch (Exception e) {e.printStackTrace();Log.i(null, e.toString());}} }); 支持相應文件圖片上傳的話:
String path="http://sv1.livechano.com:8080/upload.action?&action=1.6&type=1&ext=png";File myFile = new File("/sdcard/test.png");RequestParams params = new RequestParams();try {params.put("image", myFile,"application/octet-stream");AsyncHttpClient client = new AsyncHttpClient();client.post(path, params, new AsyncHttpResponseHandler(){@Overridepublic void onFailure(Throwable error, String content) {// TODO Auto-generated method stubsuper.onFailure(error, content);Toast.makeText(MainActivity.this, "上傳失敗!"+content, Toast.LENGTH_LONG).show();}@Overridepublic void onSuccess(int statusCode, String content) {// TODO Auto-generated method stubsuper.onSuccess(statusCode, content);System.out.println("content: "+content);Toast.makeText(MainActivity.this, "上傳成功!"+content, Toast.LENGTH_LONG).show();}});} catch(FileNotFoundException e) {} 更多參考:

http://my.oschina.net/penngo/blog/488128

http://www.cnblogs.com/manuosex/p/3583775.html
http://blog.csdn.net/wangwei_cq/article/details/9453345
http://blog.csdn.net/yanbober/article/details/45307549
http://www.cnblogs.com/angeldevil/p/3729808.html
http://blog.csdn.net/finddreams/article/details/50887506

http://www.open-open.com/lib/view/open1438784972504.html

http://blog.csdn.net/redarmy_chen/article/details/26980613











總結

以上是生活随笔為你收集整理的Anroid-async-http封装网络请求框架源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

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

久久久久久久久网站 | 激情综合网天天干 | 亚洲永久精品在线 | 精品久久久久久国产偷窥 | 欧美精品一区二区三区四区在线 | 91欧美日韩国产 | 色婷婷免费视频 | 国内精品久久久久久中文字幕 | 日韩精品久久一区二区三区 | 天堂av网站 | 久久一视频| 国产成人免费观看久久久 | 91麻豆精品| 精品久久久久久亚洲综合网 | 99精品视频在线观看视频 | www.亚洲精品 | 91久久国产自产拍夜夜嗨 | 日本高清dvd | 亚洲综合小说 | 99国产一区| 久久国产精彩视频 | 免费日韩一区二区 | av网站在线观看免费 | 人人爱在线视频 | 亚洲乱亚洲乱亚洲 | 久久天天拍| 激情久久久久 | 狠狠色狠狠色综合日日92 | 毛片网在线观看 | 一区二区三区电影 | 久久er99热精品一区二区三区 | 91麻豆精品国产91久久久使用方法 | 人人爽人人爽av | 国产色网| 色婷婷国产精品 | av观看免费在线 | 日韩电影中文字幕在线 | 亚洲综合视频在线播放 | 麻豆传媒视频观看 | 亚州精品视频 | 国产亚洲视频在线免费观看 | 久热色超碰 | 国产999在线| 色婷婷久久 | 成人app在线免费观看 | 国产精品系列在线观看 | 国产中文在线播放 | 成人av电影免费在线观看 | 天天摸天天舔 | 免费性网站 | 日本丶国产丶欧美色综合 | 国产高清成人av | 人人爽人人爽人人 | 69国产成人综合久久精品欧美 | 国产一区二区三区免费观看视频 | 欧美日韩国产一区二区在线观看 | 天天干天天做 | 在线观看黄色免费视频 | 国产高清成人av | 色五月成人| 久久精品在线 | 亚洲视频资源在线 | 精品播放 | 天天做天天爱天天爽综合网 | 国产精品s色 | 黄色网免费 | 久久久免费网站 | 一区二区久久久久 | 精品久久电影 | 亚洲国产操 | 欧美日韩1区 | 成人毛片在线观看视频 | 激情丁香综合 | av成人免费在线观看 | 黄色最新网址 | 亚洲在线免费视频 | 亚洲 欧美 精品 | 天天综合天天综合 | 免费视频你懂得 | 亚洲一区二区天堂 | 69夜色精品国产69乱 | 欧洲精品久久久久毛片完整版 | 亚洲 欧美 综合 在线 精品 | 最近免费中文视频 | 国产99视频在线观看 | 麻豆综合网 | 日韩大片在线 | 91精品91| zzijzzij日本成熟少妇 | 日韩特黄一级欧美毛片特黄 | 精品国产电影一区二区 | 久久99久久99免费视频 | 91中文字幕在线播放 | 99国产在线观看 | 欧美日韩精品影院 | 深夜免费福利网站 | av成人黄色| 久久一线| 久久久久一区 | 五月婷婷婷婷婷 | www.狠狠插.com | 成人午夜精品 | 日韩激情小视频 | 91视频91色| 久草资源在线 | 91完整版在线观看 | 欧美美女一级片 | 夜夜视频欧洲 | 伊人电影天堂 | 三上悠亚一区二区在线观看 | 久久久久久久久久国产精品 | 97成人精品 | 欧产日产国产69 | 国产精品久久久区三区天天噜 | 久久精品牌麻豆国产大山 | 九色视频网 | 色多多视频在线观看 | 欧美激情视频免费看 | 91麻豆精品国产91久久久久久 | 午夜国产在线观看 | 久久黄色免费观看 | 国产中文字幕免费 | 成人影视免费看 | 精品美女国产在线 | 在线免费91| 香蕉手机在线 | 久久综合狠狠综合久久狠狠色综合 | 亚洲精品成人网 | 99草视频 | 久久精品国产精品 | 久久伊人八月婷婷综合激情 | 免费在线看成人av | 国产一级特黄毛片在线毛片 | 九九热精品国产 | 亚洲爱视频 | 成人av免费播放 | 国产精品 欧美 日韩 | 欧美精品久久久久久久亚洲调教 | 9i看片成人免费看片 | 亚洲高清av | 怡红院成人在线 | 99热.com | 激情欧美一区二区免费视频 | 久久国色夜色精品国产 | 99r精品视频在线观看 | 摸bbb搡bbb搡bbbb | 91豆花在线观看 | 久久精品中文字幕一区二区三区 | 日韩91在线 | 日韩欧美xxx | 黄色三级在线 | 亚洲桃花综合 | 久久优 | 日本三级久久久 | 91视频 - 88av| 在线观看亚洲电影 | 精品在线99| 女人18片毛片90分钟 | 亚洲精品乱码久久久久久写真 | 探花视频网站 | 久久伊人爱 | 亚洲三级国产 | 九九视频热 | 亚洲老妇xxxxxx | 午夜在线日韩 | 精品国产人成亚洲区 | 亚洲黄a| 99精品视频在线 | 午夜av免费在线观看 | 成人国产精品久久久 | 性日韩欧美在线视频 | 99热手机在线 | 亚洲婷婷伊人 | 日韩中文在线字幕 | 涩涩伊人 | 久久精品视频网站 | 色婷婷视频在线 | 国产精品去看片 | 天堂中文在线播放 | 国产精品久久久久久久久软件 | 亚洲精品高清一区二区三区四区 | 国产资源av| 成年人免费电影 | 天天天天爱天天躁 | 日韩乱码在线 | 一级国产视频 | a在线观看视频 | 外国av网 | 超碰人在线 | 日韩无在线| 一区二区视频在线免费观看 | 亚洲男模gay裸体gay | 黄a网| 亚洲视频精品在线 | 91丨九色丨高潮丰满 | 69视频永久免费观看 | 在线v片免费观看视频 | 97人人人| 麻豆视频观看 | 中文字幕av播放 | 在线播放日韩 | 黄色av一级| 国产精品久久久一区二区 | 在线观看黄色免费视频 | 天天干 天天摸 天天操 | 久久综合久久综合这里只有精品 | 久久免费视屏 | 亚洲精品成人网 | 看黄色.com | 久久综合射 | 久久精彩视频 | 91成人精品一区在线播放69 | 久久九九久久九九 | 国产成人精品电影久久久 | 伊人导航 | 国产精品久久久av | 国产精品久久久久久一区二区三区 | 黄色三几片 | 97国产情侣爱久久免费观看 | 99久久精品国产免费看不卡 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 亚洲日本精品视频 | 国产成人精品一区二区三区福利 | 欧美国产日韩一区二区 | 亚洲精品在线播放视频 | 九九交易行官网 | 美女黄频视频大全 | 欧洲性视频 | 久99久精品视频免费观看 | 欧美成人一二区 | 亚洲精品国产综合久久 | 久久亚洲成人网 | 国产午夜影院 | 最近日本中文字幕a | 能在线观看的日韩av | 中文字幕123区 | 亚洲国产欧美在线看片xxoo | 久久精品免视看 | 中文字幕乱码电影 | 久久久久久毛片精品免费不卡 | 99精品视频精品精品视频 | 欧美日韩在线视频免费 | 丁香婷婷久久 | 久久久三级视频 | 亚洲影院一区 | av黄网站| 亚洲精品啊啊啊 | 美女一级毛片视频 | 国产91在线 | 美洲 | 黄色免费大全 | 97在线观看免费高清 | 久久综合狠狠综合 | 欧美一区在线观看视频 | a视频免费 | 亚洲精品视频网 | 国产一级不卡毛片 | 999免费视频 | 亚洲精品黄色在线观看 | 91av视频| 日韩欧美视频二区 | 精品国产一二三四区 | 99精品欧美一区二区三区黑人哦 | 少妇精69xxtheporn | avove黑丝 | 特黄特黄的视频 | 国产亚洲精品久久久久久久久久 | 国产一区免费视频 | 天天干 天天摸 天天操 | 亚洲欧美精品一区 | 国产精品毛片一区二区在线 | 综合激情久久 | 欧美午夜寂寞影院 | 91九色国产视频 | 国产成人精品av久久 | av短片在线观看 | 国产精品久久久久久久久费观看 | 色国产精品 | 亚洲精品视频免费 | 欧洲高潮三级做爰 | 日韩在线观看第一页 | 99视频一区二区 | 日韩在线不卡视频 | 欧美精品在线观看一区 | 免费av大片 | 在线观看av网 | 国产在线一卡 | 国产视频亚洲视频 | 天天色宗合 | 日韩欧美在线免费观看 | 在线免费观看的av | 91视频com | 亚洲国产精品激情在线观看 | 成人在线观看影院 | 国产免费高清视频 | 激情婷婷久久 | 成人黄色电影在线 | 成人午夜精品久久久久久久3d | 免费成人黄色av | 在线播放视频一区 | 香蕉在线影院 | 婷婷国产精品 | 天天干人人 | 日韩欧美综合精品 | 狠狠久久婷婷 | 日韩在线观看小视频 | 欧美午夜久久久 | 97人人澡人人爽人人模亚洲 | 天天操天天摸天天射 | 国产不卡在线看 | 久久久国产精品亚洲一区 | 97国产大学生情侣酒店的特点 | 丁香五月亚洲综合在线 | 欧美一区二区三区在线看 | 国产精品成人免费 | 亚洲最大在线视频 | 免费观看第二部31集 | 中文字幕av日韩 | 久久综合婷婷国产二区高清 | 亚洲国产中文字幕在线视频综合 | 免费久久久久久 | 国产精品99爱 | 91麻豆看国产在线紧急地址 | 午夜手机电影 | 久久久久女教师免费一区 | 国产超碰在线 | 在线观看国产一区 | 激情电影影院 | 亚洲精品美女在线 | 五月天综合在线 | 最近中文字幕在线 | 一级黄色片毛片 | 制服丝袜一区二区 | 最近2019中文免费高清视频观看www99 | 精品国产精品久久一区免费式 | 国产精品一区二区在线观看免费 | 超碰人人超 | 国产 欧美 日本 | 成人免费观看完整版电影 | 国产中文字幕在线 | 亚洲国产成人久久综合 | 成人av网址大全 | 亚洲欧洲日韩 | 欧美电影在线观看 | 日韩婷婷 | 久久国产手机看片 | 国产视频一级 | av在线中文 | 天天色天天草天天射 | 欧美在线aaa| 成人免费亚洲 | 不卡电影一区二区三区 | 黄色小说视频网站 | 欧美在线观看视频免费 | 天堂在线视频中文网 | 欧美怡红院 | 在线观看视频免费播放 | 亚洲国产精久久久久久久 | 国产精品乱码一区二三区 | 免费情缘 | .国产精品成人自产拍在线观看6 | 亚洲一区免费在线 | 国产正在播放 | 国产小视频免费观看 | 免费视频一区二区 | 蜜桃传媒一区二区 | 国产91精品一区二区绿帽 | 天天干,狠狠干 | 午夜精品成人一区二区三区 | 91视频一8mav | 午夜视频在线观看一区 | 色成人亚洲网 | 久久中文欧美 | 超碰97人人在线 | 一区二区三区四区五区在线 | 日韩三级不卡 | a天堂最新版中文在线地址 久久99久久精品国产 | 成人免费共享视频 | 久久久电影网站 | 久久久久女人精品毛片 | 免费av在 | 国产精品不卡在线 | 国产韩国日本高清视频 | 国产精品情侣视频 | 99久久www免费 | 国产日韩视频在线播放 | 亚洲精品在线视频网站 | 日韩在线视频一区 | www.久久91| 天天干天天操天天拍 | 久草网站在线观看 | 91亚洲精品久久久中文字幕 | 国内精品久久久久影院一蜜桃 | 久久婷婷丁香 | 一区二区三区中文字幕在线观看 | 毛片一级免费一级 | 日韩免费久久 | 国产v视频 | 中文字幕 国产 一区 | 狠狠色丁香婷婷综合最新地址 | 成人网在线免费视频 | 看片网站黄色 | 九九热re | 亚洲日本成人网 | 久久综合亚洲鲁鲁五月久久 | 免费视频成人 | 婷婷狠狠操 | 天天躁天天操 | 亚洲伊人色 | 婷婷在线视频观看 | 成人免费中文字幕 | 在线91精品 | 日韩视频免费观看高清完整版在线 | 国产视频精品在线 | 国产精品久久久久久久久久尿 | 深夜视频久久 | 日韩精品一区二区三区中文字幕 | 日韩欧美视频免费观看 | 精品国产一区二区三区在线 | 国产精品美女免费看 | 成人国产精品久久久 | 亚洲伊人网在线观看 | 国产精品毛片完整版 | 国产精品久久久999 国产91九色视频 | 久久99精品波多结衣一区 | 日韩欧美在线中文字幕 | 中文字幕日韩在线播放 | www.午夜| 999久久久久久久久 69av视频在线观看 | 国产九九九精品视频 | 三级黄色理论片 | 婷婷久久婷婷 | 91人人澡人人爽 | 国产一级做a爱片久久毛片a | 日韩免费av网址 | 国产成人一区二区三区久久精品 | 天天色棕合合合合合合 | 亚洲丝袜中文 | 麻豆成人小视频 | 91九色综合| 国产亚洲精品久久久久久电影 | 免费在线成人av电影 | 免费观看9x视频网站在线观看 | 中文字幕色播 | 中文字幕在线日亚洲9 | 国产 视频 久久 | 亚洲国产精品影院 | 色视频在线看 | 日韩在线视频观看免费 | 四虎永久免费在线观看 | www色网站| 久久99精品久久久久婷婷 | 99热这里只有精品免费 | 在线观看免费视频你懂的 | 国产精品com | 色天天综合久久久久综合片 | 日本精品中文字幕在线观看 | 中日韩在线视频 | 亚洲精品一区二区久 | 国产免费高清视频 | 日本黄色片一区二区 | 人人玩人人添人人 | 美女久久久久久 | 中文字幕乱在线伦视频中文字幕乱码在线 | 九九精品视频在线看 | 日韩欧美在线视频一区二区三区 | 一级片色播影院 | 字幕网在线观看 | www国产亚洲精品久久网站 | 亚洲专区 国产精品 | 国内成人av| 在线电影a | 成人91免费视频 | 成人免费观看大片 | 国产午夜av | 99久久久| 欧美精彩视频在线观看 | 97视频入口免费观看 | 狠狠狠狠狠狠狠狠 | 日韩在线观看影院 | 国产亚州精品视频 | 日韩免费av片 | 91麻豆精品国产91久久久使用方法 | 99综合电影在线视频 | 在线播放国产精品 | 久久久精品久久日韩一区综合 | 成年人在线观看视频免费 | 国产精品久久久久久久av电影 | 91网页版免费观看 | 精品免费观看 | 在线免费av电影 | 成人午夜电影在线播放 | 久久精品视频4 | 91成年视频 | 精品视频亚洲 | 五月网婷婷 | 天天干天天干天天色 | 91女神的呻吟细腰翘臀美女 | 少妇自拍av| 成人免费视频免费观看 | 日韩在线一区二区免费 | 精品在线视频观看 | 夜添久久精品亚洲国产精品 | 激情影音先锋 | 久久永久视频 | 国产成人精品久久 | 日韩三级视频在线观看 | 91精品国产高清 | 久久精品国产99国产 | 亚洲午夜av| 久久久久久久影院 | 亚洲综合婷婷 | 五月婷婷在线视频观看 | 天天碰天天操视频 | 亚洲国产网站 | av免费试看 | 久久免费视频国产 | 日韩av电影网站在线观看 | 国产午夜影院 | 国产99久久久国产精品免费看 | 国产 在线 高清 精品 | 天天操狠狠操夜夜操 | 在线亚洲欧美视频 | 国产精品孕妇 | 色综合婷婷 | 亚洲精品午夜久久久久久久 | 在线网址你懂得 | av网址最新 | 狠狠干美女 | 日韩精品久久久久久久电影99爱 | 天天射天天爱天天干 | 成人av教育 | 久久人视频| 亚洲精品在线观看的 | 成人av网页 | 亚洲国产97在线精品一区 | 中文字幕影片免费在线观看 | 操天天操| 综合激情伊人 | 国产中文在线视频 | 成人毛片网 | 日韩一级精品 | 国产日韩欧美在线观看 | 天天射天天做 | 天海冀一区二区三区 | 成人一区在线观看 | 久久精彩 | 99久久精品国产毛片 | 六月婷操 | 国产精品嫩草影院99网站 | 午夜视频免费在线观看 | 亚洲视屏一区 | 97色狠狠| 欧美性色黄大片在线观看 | 日韩激情av在线 | 日本最新高清不卡中文字幕 | 玖玖视频国产 | 中文字幕欧美日韩va免费视频 | 九色琪琪久久综合网天天 | 韩国精品在线观看 | av电影中文字幕 | 国产不卡视频 | 在线精品视频在线观看高清 | 美女视频一区二区 | 六月婷婷久香在线视频 | 国产精品久久久久久久久久久久久 | 九九九热视频 | 国产99久久99热这里精品5 | 一个色综合网站 | 在线中文字幕网站 | 91尤物国产尤物福利在线播放 | 亚洲影音先锋 | www.伊人网.com| 久久爱导航 | 午夜在线免费观看视频 | 91大神dom调教在线观看 | 黄色aa久久 | 97视频中文字幕 | 91在线网站| 久久在现视频 | 日韩精品免费一区二区 | 国产在线视频导航 | 国产福利91精品 | 97夜夜澡人人双人人人喊 | 日韩欧在线 | 操久久免费视频 | 天天综合天天综合 | 91精品影视 | 日韩免费 | 日韩在线电影一区二区 | 在线色网站| 国产视频97| 精品免费观看 | 亚洲少妇天堂 | 亚洲精品五月 | 高清有码中文字幕 | 草久在线观看视频 | 亚洲成人黄色 | 国产视频资源在线观看 | 色就是色综合 | 日韩av成人在线观看 | 久久国产高清 | 狠狠色综合网站久久久久久久 | 精品日本视频 | av中文字幕在线播放 | 国产精品综合av一区二区国产馆 | 美女网站视频色 | 天天干天天插伊人网 | 东方av在| 99视频久 | 国产手机视频在线 | 成人av电影免费 | 欧美小视频在线观看 | 四虎精品成人免费网站 | 亚洲国产欧美在线人成大黄瓜 | 亚洲成人资源在线观看 | 97久久精品午夜一区二区 | 色五月成人 | 久久夜色精品国产欧美乱 | av在线网站大全 | 天天射天天干天天操 | 精品久久久精品 | 国产成人精品一区二区三区在线 | 免费观看www7722午夜电影 | 日本精品久久久久中文字幕5 | 久久极品| 精品视频 | zzijzzij亚洲日本少妇熟睡 | 99久久www | 免费视频三区 | 欧美日韩视频在线播放 | 二区三区中文字幕 | 久久精品xxx | 久久久av免费 | 日韩精品一区二区三区视频播放 | 亚洲婷婷网| 久久久69| 日韩黄色一级电影 | 中文字幕在线高清 | 成人 国产 在线 | 婷婷电影在线观看 | 欧美一级黄色视屏 | 国产精品99久久久久久久久久久久 | 91网站免费观看 | 国产一级二级视频 | 亚洲精品成人av在线 | 中文字幕综合在线 | 国产精品一区二区免费在线观看 | 91精品久久久久久粉嫩 | 国产精品成人免费精品自在线观看 | 精品久久电影 | 欧美影片| 精品国产欧美 | 正在播放一区二区 | 色婷婷色 | 中文字幕国产一区二区 | 久草视频中文在线 | 国产精品不卡 | 精品亚洲视频在线 | 超碰在线色 | 色狠狠狠 | 久久久麻豆视频 | 国产真实精品久久二三区 | 免费毛片一区二区三区久久久 | 99热这里有 | www.久久视频 | 日本精品一二区 | 国产国语在线 | 久久激情五月婷婷 | 国产精品麻豆99久久久久久 | 国产精品手机视频 | 精品国产免费一区二区三区五区 | 日本黄色免费电影网站 | 久久伊人综合 | 中文一二区 | 免费视频91| 免费网站在线观看成人 | 欧美日韩高清在线一区 | av亚洲产国偷v产偷v自拍小说 | 日韩一区二区三区不卡 | 丝袜美腿亚洲 | 91精品国产九九九久久久亚洲 | 国产剧情一区二区在线观看 | 黄色影院在线免费观看 | 欧美在线观看视频 | 中文字幕人成人 | 在线看一区 | 色综久久 | 视频一区亚洲 | 久久视频网址 | 国产成人精品999 | 四虎国产精品免费观看视频优播 | 国产一区二区久久久 | a在线免费观看视频 | 精品国产aⅴ麻豆 | 亚洲一区二区高潮无套美女 | 色噜噜日韩精品欧美一区二区 | 亚洲爱爱视频 | 2021国产精品视频 | 国产999精品久久久久久 | 青草草在线 | 色综合五月天 | 日韩av综合网站 | 国产不卡一 | 国产午夜精品免费一区二区三区视频 | 亚洲精品一区二区网址 | 午夜精品久久久久久久99 | 亚洲欧洲在线视频 | 亚洲精品视频在线观看网站 | 2023年中文无字幕文字 | 国产专区免费 | 又黄又爽又无遮挡的视频 | 在线观看免费国产小视频 | 国产在线一区观看 | 黄色a三级| 91亚洲国产成人久久精品网站 | 中文av资源站 | 又爽又黄又刺激的视频 | 久久综合操 | 久久99精品久久久久久清纯直播 | 国产偷国产偷亚洲清高 | 欧美日本啪啪无遮挡网站 | 亚洲成av人片在线观看www | 亚洲激情综合网 | 午夜婷婷综合 | 米奇狠狠狠888 | 精品欧美乱码久久久久久 | 国产粉嫩在线 | 成年人视频在线 | 国产一区麻豆 | 伊人天天操 | 亚洲成年人免费网站 | 国内精品久久久久久久 | 91一区啪爱嗯打偷拍欧美 | 久久这里有 | 亚洲一区二区高潮无套美女 | 久久精品视频4 | 亚洲国产日本 | 最新极品jizzhd欧美 | 人人干在线观看 | 国产中文在线观看 | 成人夜晚看av | a级国产乱理论片在线观看 特级毛片在线观看 | 色老板在线视频 | 狠狠色婷婷丁香六月 | 色小说在线 | 天堂素人在线 | 五月天欧美精品 | 免费激情在线电影 | 在线黄色毛片 | 日韩h在线观看 | 天天色 天天| 香蕉视频在线免费 | 亚洲精品videossex少妇 | 精品国产aⅴ麻豆 | 免费一级片在线观看 | 深夜福利视频在线观看 | 成人四虎影院 | 亚洲精品h | 91九色最新地址 | 久久久精品电影 | 国产亚洲精品久久久久久无几年桃 | 粉嫩高清一区二区三区 | 日韩欧美综合 | 91麻豆精品国产91久久久久久久久 | h文在线观看免费 | .精品久久久麻豆国产精品 亚洲va欧美 | 国产小视频你懂的 | 欧美日韩亚洲在线 | 久久久久久国产精品亚洲78 | 国内精品久久久久影院一蜜桃 | 亚洲第一区在线观看 | 欧美日韩视频在线观看免费 | 五月婷婷黄色 | 米奇影视7777| 日韩欧美在线高清 | 欧美午夜精品久久久久久浪潮 | 婷婷六月天丁香 | 久久久久久久久久免费视频 | 日女人免费视频 | 91丝袜美腿 | 天天天天爱天天躁 | 国产亚洲欧美在线视频 | 国产成人在线播放 | 久久免费av电影 | 波多野结衣日韩 | 九九久久婷婷 | 99精品视频免费看 | 国产日韩在线播放 | 中文字幕视频网 | 美女久久久 | 久久tv| 欧美一级片免费在线观看 | 亚洲成人av电影在线 | 热久久99这里有精品 | 亚洲aⅴ乱码精品成人区 | 精品999| 中文字幕传媒 | 日韩啪视频 | 成人丝袜| 日本中文一级片 | 久久99精品国产99久久6尤 | 欧美 日韩 国产 中文字幕 | 国产在线精品观看 | 国产精品麻豆视频 | 91漂亮少妇露脸在线播放 | 天天干天天干天天 | 国产成人综合图片 | 天天插天天| 在线电影日韩 | 久久久.com | 91激情小视频 | 中文字幕乱偷在线 | 中文字幕第一页av | 欧美精品在线视频 | 91视频免费国产 | 精品在线观看一区二区 | 国产69熟 | 日韩免费播放 | 日韩三级视频在线看 | 五月婷婷六月丁香激情 | 成人免费xxx在线观看 | 亚洲a免费 | 青青草在久久免费久久免费 | 99精品美女| 免费热情视频 | 偷拍久久久 | 特级毛片在线观看 | 国产小视频在线观看免费 | 国产一区二区三区久久久 | 久久综合婷婷 | 日本精品视频一区二区 | 亚洲欧洲国产日韩精品 | 欧美亚洲国产一卡 | 99精品免费| 亚洲人xxx| 九色琪琪久久综合网天天 | 国产成人亚洲在线观看 | 国产中文在线字幕 | 在线视频成人 | 精品国产1区2区 | 国产亚洲一区二区在线观看 | 狠狠色免费 | 九色porny真实丨国产18 | 成人黄色在线 | 久热只有精品 | 免费电影播放 | 国产不卡免费 | av在线免费不卡 | 国产精品99久久久精品免费观看 | 激情综合网五月婷婷 | 日本视频久久久 | 亚洲伦理电影在线 | 久久免费福利视频 | 青青视频一区 | 精品一区在线 | 在线va网站| 黄色av电影网 | 国产精品视频免费在线观看 | 成人在线一区二区 | 欧美午夜理伦三级在线观看 | 激情av网址 | 香蕉久久久久久久 | 婷婷丁香花五月天 | 久久五月婷婷丁香 | 亚洲最新视频在线播放 | 欧美午夜一区二区福利视频 | 99热精品国产一区二区在线观看 | 成人aaa毛片 | 亚洲国产欧美在线看片xxoo | 中文字幕在线观看网 | 亚洲精品乱码久久久久久9色 | 婷婷久久五月 | 右手影院亚洲欧美 | 日本精品视频一区二区 | 黄色av影视 | 韩日精品视频 | 国产精品福利午夜在线观看 | 中文字幕乱码在线播放 | 中文永久字幕 | 久久福利 | 午夜av影院| 免费手机黄色网址 | 久久久精品在线观看 | 怡红院久久 | 成年人视频在线免费 | 91丨九色丨91啦蝌蚪老版 | 九九爱免费视频 | 欧美日韩在线免费观看视频 | 天天操比 | 久草视频在线新免费 | 精品久久久亚洲 | 国产精品一区二区在线观看免费 | 亚洲国产一区在线观看 | ww亚洲ww亚在线观看 | 日韩欧美黄色网址 | 日韩电影一区二区在线观看 | 伊人五月天 | 五月导航 | 四虎在线观看 | 91高清视频在线 | 国产一区二区三区午夜 | av日韩不卡 | 国产中文字幕在线观看 | 人人爽人人舔 | 手机av电影在线观看 | 日韩黄色一级电影 | 午夜123 | 色瓜 | 国产美女视频 | 激情五月av | 主播av在线 | 91久久久国产精品 | 日韩高清在线一区 | 51久久夜色精品国产麻豆 | 天天干天天干天天干天天干天天干天天干 | 在线 视频 亚洲 | 久草在线中文视频 | 久久九九精品久久 | 日韩不卡高清视频 | 91精品国产麻豆国产自产影视 | 精品国产一区二区三区男人吃奶 | 91大神精品视频 | 国产午夜精品一区二区三区四区 | 久草观看 | 国产精品入口麻豆 | 91.dizhi永久地址最新 | 欧美在线观看小视频 | www.伊人网| 久久精品人 | 国产精品久久久久久久久久久不卡 | 久久久免费观看 | 亚洲人成人在线 | 中文字幕一区在线观看视频 | 日韩欧美视频二区 | 日本最新高清不卡中文字幕 | 五月婷婷操 | 成人av在线网址 | 精品久久亚洲 | 天天天天综合 | 精品99久久久久久 | 久久这里只有精品23 | 黄色精品一区二区 | 国产一区成人在线 | 日日夜夜精品 | 亚洲黄色网络 | 免费观看一级成人毛片 | 国产高清视频色在线www | 夜夜夜夜猛噜噜噜噜噜初音未来 | 日韩在线大片 | 免费观看黄色12片一级视频 | 在线观看日韩视频 | 国产精品久久在线观看 | 超碰人人乐 | 成人va视频| 精品久久精品 | 国产黑丝袜在线 | 久久99视频免费 | 在线观看黄色 | 免费a级大片 | av在线收看 | 欧美国产日韩中文 | 中文有码在线 | 粉嫩av一区二区三区入口 | av 一区 二区 久久 | 亚州av网站 | 一区二区丝袜 | 成人黄色片免费 | 视频在线观看99 | 最新av网站在线观看 | av免费在线观看网站 | 91av原创| 精品国产一区二区三区久久影院 | 91麻豆国产 | 日韩在线网| 久久久久久久国产精品影院 | 欧美性生活免费看 | 99久久国产免费看 | 最近免费观看的电影完整版 | 在线国产视频观看 | 国产精品午夜久久久久久99热 | 久久97精品| 国产免费观看久久黄 | 亚洲欧美日韩一区二区三区在线观看 | av中文字幕在线观看网站 | 97人人澡人人爽人人模亚洲 | 久久免费视频7 | 久久精品久久精品久久 | 中文字幕视频网站 | 六月色丁香 | 在线亚洲午夜片av大片 | 久久国产手机看片 | 天堂网av在线 | 免费在线观看日韩欧美 | 成人av免费 | 婷婷色站 | www.伊人色.com| 久久午夜网 | 伊在线视频 |