1. 程式人生 > >用谷歌的AsyncHttpClient簡單模仿安卓的AsyncHttpClient,實現非同步請求回撥函式返回值

用谷歌的AsyncHttpClient簡單模仿安卓的AsyncHttpClient,實現非同步請求回撥函式返回值

實現思路

既然要呼叫Future.get() 才能激發訪問,那麼就想到了使用一個執行緒去訪問。我們就不需要等待阻塞了。
模仿安卓的AsyncHttpClient回撥。根據狀態回撥不同的函式。

實現的效果

    執行程式碼...
    非同步請求..不需要等待返回的結果,繼續執行下面的程式碼
    執行程式碼...

AsyncHttpClient 主工具類

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import
java.util.concurrent.Executors; import java.util.concurrent.Future; import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.Response; /** * AsyncHttpClient請求工具箱 * * @author Zq * */ public class AsyncHttpKit { private AsyncHttpKit() { }; /** 預設編碼 **/ private static
final String DEFAULT_CHARSET = "UTF-8"; /** 非同步請求物件 **/ private static AsyncHttpClient http = new AsyncHttpClient(); /** 快取執行緒池 **/ private static ExecutorService pool = Executors.newCachedThreadPool(); /** * * @param url 訪問連結,但是請注意,接收的url 必須符合URI協議,否則丟擲異常 * @param params 引數,其中不能有為null的引數值 * @param
handler 非同步回撥輔助類 */
public static void post(String url, Map<String, String> params,AsyncHttpResponseHandler handler){ handler.setFuture(post(url, params)); pool.execute(handler); } /** * 非同步Post請求 * * @param http * @param url * @param params * 請求引數 * @return */ private static Future<Response> post(String url, Map<String, String> params) { AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url); builder.setBodyEncoding(DEFAULT_CHARSET); if (params != null && !params.isEmpty()) { Set<String> keys = params.keySet(); for (String key : keys) { builder.addParameter(key, params.get(key)); } } Future<Response> f = null; try { f = builder.execute(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return f; } /** * 非同步post請求 * @param url 請求地址 * @param s 引數為 json串 {xx:xx,...} * @param handler */ public static void post(String url,String s,AsyncHttpResponseHandler handler){ handler.setFuture(post(url, s)); pool.execute(handler); } /** * 非同步POST請求 * * @param http * @param url * @param s * json串 * @return */ private static Future<Response> post(String url, String s) { AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url); builder.setBodyEncoding(DEFAULT_CHARSET); builder.setBody(s); Future<Response> f = null; try { f = builder.execute(); } catch (IOException e) { e.printStackTrace(); } return f; } }

輔助類,模仿安卓的AsyncHttpResponseHandler

安卓的非同步請求
<dependency>  
    <groupId>com.loopj.android</groupId>  
    <artifactId>android-async-http</artifactId>  
    <version>1.4.5</version>  
</dependency>  
import java.util.concurrent.Future;

import com.ning.http.client.Response;

/**
 * 非同步請求輔助類
 * @author Zq
 *
 */
public abstract class AsyncHttpResponseHandler implements Runnable {
    private Future<Response> future = null;

    @Override
    public void run() {
        int statusCode = 0;
        try {
            Response response = future.get(/*timout, TimeUnit.SECONDS*/);
            statusCode = response.getStatusCode();
            String responseBody = response.getResponseBody("UTF-8");
            if (statusCode == 200) { //只有200狀態呼叫成功方法
                this.onSuccess(statusCode, responseBody);
            } else { //其他狀態呼叫失敗方法
                this.onFailure(statusCode, responseBody,null);
            }
        } catch (InterruptedException e) { //請求過程中出現錯誤,請求狀態變成0,呼叫失敗的方法
            this.onFailure(0, null, e);
        } catch (ExecutionException e) {
            this.onFailure(0, null, e);
        } catch (IOException e) {
            this.onFailure(statusCode, null, e);
        }
        /**
         * 上面的處理過程,需要子類實現者手動的try掉onFailure和 onSuccess中的所有異常,否則會出現呼叫結果不準確的現象
         */
    }


    /**
     * 請求成功:回撥函式
     * 
     * @param status
     *            狀態碼 200
     * @param body
     *            返回結果
     */
    public abstract void onSuccess(int status, String body);

    /**
     * 請求失敗回撥函式
     * 
     * @param status
     *            除了200意外的所有狀態碼;如果返回0 請求的時候發生了異常,throwable屬性有值
     * @param body
     *            返回的結果
     * @param throwable
     *            丟擲錯誤異常
     */
    public abstract void onFailure(int status, String body, Throwable throwable);

    public Future<Response> getFuture() {
        return future;
    }

    public void setFuture(Future<Response> future) {
        this.future = future;
    }
}