Android HTTP網路請求的非同步實現

Android HTTP網路請求的非同步實現
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

前言

大家都知道網路操作的響應時間是不定的,所有的網路操作都應該放在一個非同步操作中處理,而且為了模組解耦,我們希望網路操作由專門的類來處理。所有網路資料傳送,資料接收都有某幾個類來實現,外部其它模組只要呼叫和處理回撥函式即可。外部模組和網路模組之間的呼叫關係可以用如下圖表示:

呼叫端只要建立Request物件,設定引數,發起請求,即可。最後結果通過回撥函式返回。右邊的非同步任務,HttpClient建立,引數解析,錯誤處理全部交給網路處理模組來完成。由此來看,這個網路模組其實是重複性很高的開發工作,為了避免重複造輪子,下面就給大家介紹下我們工作中實現的網路操作模組及相應類的實現。

1.呼叫端程式碼:

Get或Post請求


protected void doWebTest()
{
String url = "http://www.target.com/abcd";
try {
MyHttpRequest http = new MyHttpRequest(url);
//如果是Post請求,則設定.如果是get請求,請不要設定post引數
//http.addPost("data", "testpostvalue");
//post引數結束,get請求,不要新增上面addPost程式碼
http.addHeader("Accept", "text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
http.addHeader("Accept-Encoding", "gzip, deflate, sdch");
http.addHeader("Accept-Language","zh-CN,zh;q=0.8");
http.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36");
http.StartRequest(new INetResponseListener() {
@Override
public void OnRequestComplete(NetResponse result) {
if(result.isSuccess())
{
String resultStr = result.resultStr;
//resultStr就是網路返回的資料
}else
{
Exception ee = result.getException();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

以上是呼叫端需要實現的原始碼,是不是很少程式碼就可以完成網路請求?下面就為大家揭開這個網路處理類的面紗。

2.主要類介紹
 1.AbstractRequester:一個抽象的網路請求類
 2.MyHttpRequest::例項化的網路請求類。如果開發者有其它特殊處理需求,可以繼承AbstractRequester 自己重新實現parseResponse
 3.HttpEngine:HttpClient網路引擎類,最終的網路請求由這個類處理
 4.HttpRequestData:傳遞給AsyncTask的引數類
 5.NetResponse:返回給呼叫者的響應類
 6.INetResponseListener:非同步回撥的interface

類之間的關係如下圖所示:

2.1 AbstractRequester
抽象的網路管理類,類定義如下:


public abstract class AbstractRequester extends AsyncTask<HttpRequestData,Integer,NetResponse> {
...
/**
* 根據需求建立傳遞給http傳送的引數
* @return
*/
abstract HttpRequestData createData();
/**
* 根據返回的流,解析生成相應的物件
* @param in
* @return
*/
abstract NetResponse parseResponse(InputStream in);
//執行完成後的回撥函式 
protected void onPostExecute(NetResponse result) {
super.onPostExecute(result);
if(listener!=null)
{
listener.OnRequestComplete(result);
}
}
//網路請求開始處理
protected NetResponse doInBackground(HttpRequestData... reqArgs) {
//因內容比較多。具體檢視原始碼
}
public void StartRequest(INetResponseListener aListener){
//具體檢視原始碼
}
}

對於一些有其它特殊需求的開發者,只需要繼承這個類,並實現它的抽象介面,如果是通用需求,則可以直接使用下面的MyHttpRequest類:

abstract HttpRequestData createData();
abstract NetResponse parseResponse(InputStream in);

2.2 MyHttpRequest
繼承並實現了AbstractRequester的網路處理類,支援Get和Post型別,支援自定義新增headers引數。
對於普通的網路請求和返回已經夠用,開發者可以直接使用。

2.3 HttpEngine
網路請求引擎類。主要流程如下:
 1.建立createHttpClient
 2.判斷引數有效性
 3.判斷get或post
 4.建立對應的HttpGet或HttpPost
 5.設定各類引數
 6.呼叫httpClient.execute執行網路請求
 7.解析和判斷網路返回結果
 8.生成Stream物件並返回

2.4 HttpRequestData

傳遞給AsyncTask的引數類,用於設定http請求的各類引數。

2.5 NetResponse
返回給呼叫者的類物件,包括狀態、資料和異常。

2.6 INetResponseListener
定義很簡單,原始碼如下:


public interface INetResponseListener {
/**
* 網路請求返回
* @param result
*/
public void OnRequestComplete(NetResponse result);
}

呼叫者只要實現這個interface,非同步接收返回結果即可,返回結果就是NetResponse物件。

 – 常見問題

1. AsyncTask說明
 大家都知道AsyncTask是非同步的,所以網路請求通過AsyncTask來實現,通過AyncTask的好處是輕量級非同步,而且可以操作ui執行緒,比如更新進度條等。但AsyncTask也存在以下一些問題:
 •task需要在ui執行緒中建立和啟用,所以AbstractRequester 物件的建立和呼叫StartRequest請在ui執行緒中完成
 •API 11也就是3.0以後,AsyncTask是排隊執行,所以如果其中一個任務出現較耗時,其它網路請求需要等待;如果你想同步執行,要修改execute為executeOnExecutor(但不推薦做這個修改)

2. 許可權
在xml中新增網路操作許可權:

<uses-permission android:name=”android.permission.INTERNET” />

相關文章

Android 開發 最新文章