Android HTTP網(wǎng)絡(luò)請求的異步實(shí)現(xiàn)
前言
大家都知道網(wǎng)絡(luò)操作的響應(yīng)時間是不定的,所有的網(wǎng)絡(luò)操作都應(yīng)該放在一個異步操作中處理,而且為了模塊解耦,我們希望網(wǎng)絡(luò)操作由專門的類來處理。所有網(wǎng)絡(luò)數(shù)據(jù)發(fā)送,數(shù)據(jù)接收都有某幾個類來實(shí)現(xiàn),外部其它模塊只要調(diào)用和處理回調(diào)函數(shù)即可。外部模塊和網(wǎng)絡(luò)模塊之間的調(diào)用關(guān)系可以用如下圖表示:
調(diào)用端只要創(chuàng)建Request對象,設(shè)置參數(shù),發(fā)起請求,即可。最后結(jié)果通過回調(diào)函數(shù)返回。右邊的異步任務(wù),HttpClient創(chuàng)建,參數(shù)解析,錯誤處理全部交給網(wǎng)絡(luò)處理模塊來完成。由此來看,這個網(wǎng)絡(luò)模塊其實(shí)是重復(fù)性很高的開發(fā)工作,為了避免重復(fù)造輪子,下面就給大家介紹下我們工作中實(shí)現(xiàn)的網(wǎng)絡(luò)操作模塊及相應(yīng)類的實(shí)現(xiàn)。
1.調(diào)用端代碼:
Get或Post請求
protected void doWebTest() { String url = "http://www.target.com/abcd"; try { MyHttpRequest http = new MyHttpRequest(url); //如果是Post請求,則設(shè)置.如果是get請求,請不要設(shè)置post參數(shù) //http.addPost("data", "testpostvalue"); //post參數(shù)結(jié)束,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就是網(wǎng)絡(luò)返回的數(shù)據(jù) }else { Exception ee = result.getException(); } } }); } catch (Exception e) { e.printStackTrace(); } }
以上是調(diào)用端需要實(shí)現(xiàn)的源碼,是不是很少代碼就可以完成網(wǎng)絡(luò)請求?下面就為大家揭開這個網(wǎng)絡(luò)處理類的面紗。
2.主要類介紹
1.AbstractRequester:一個抽象的網(wǎng)絡(luò)請求類
2.MyHttpRequest::實(shí)例化的網(wǎng)絡(luò)請求類。如果開發(fā)者有其它特殊處理需求,可以繼承AbstractRequester 自己重新實(shí)現(xiàn)parseResponse
3.HttpEngine:HttpClient網(wǎng)絡(luò)引擎類,最終的網(wǎng)絡(luò)請求由這個類處理
4.HttpRequestData:傳遞給AsyncTask的參數(shù)類
5.NetResponse:返回給調(diào)用者的響應(yīng)類
6.INetResponseListener:異步回調(diào)的interface
類之間的關(guān)系如下圖所示:
2.1 AbstractRequester
抽象的網(wǎng)絡(luò)管理類,類定義如下:
public abstract class AbstractRequester extends AsyncTask<HttpRequestData,Integer,NetResponse> { ... /** * 根據(jù)需求創(chuàng)建傳遞給http發(fā)送的參數(shù) * @return */ abstract HttpRequestData createData(); /** * 根據(jù)返回的流,解析生成相應(yīng)的對象 * @param in * @return */ abstract NetResponse parseResponse(InputStream in); //執(zhí)行完成后的回調(diào)函數(shù) protected void onPostExecute(NetResponse result) { super.onPostExecute(result); if(listener!=null) { listener.OnRequestComplete(result); } } //網(wǎng)絡(luò)請求開始處理 protected NetResponse doInBackground(HttpRequestData... reqArgs) { //因內(nèi)容比較多。具體查看源碼 } public void StartRequest(INetResponseListener aListener){ //具體查看源碼 } }
對于一些有其它特殊需求的開發(fā)者,只需要繼承這個類,并實(shí)現(xiàn)它的抽象接口,如果是通用需求,則可以直接使用下面的MyHttpRequest類:
abstract HttpRequestData createData();
abstract NetResponse parseResponse(InputStream in);
2.2 MyHttpRequest
繼承并實(shí)現(xiàn)了AbstractRequester的網(wǎng)絡(luò)處理類,支持Get和Post類型,支持自定義添加headers參數(shù)。
對于普通的網(wǎng)絡(luò)請求和返回已經(jīng)夠用,開發(fā)者可以直接使用。
2.3 HttpEngine
網(wǎng)絡(luò)請求引擎類。主要流程如下:
1.創(chuàng)建createHttpClient
2.判斷參數(shù)有效性
3.判斷get或post
4.創(chuàng)建對應(yīng)的HttpGet或HttpPost
5.設(shè)置各類參數(shù)
6.調(diào)用httpClient.execute執(zhí)行網(wǎng)絡(luò)請求
7.解析和判斷網(wǎng)絡(luò)返回結(jié)果
8.生成Stream對象并返回
2.4 HttpRequestData
傳遞給AsyncTask的參數(shù)類,用于設(shè)置http請求的各類參數(shù)。
2.5 NetResponse
返回給調(diào)用者的類對象,包括狀態(tài)、數(shù)據(jù)和異常。
2.6 INetResponseListener
定義很簡單,源碼如下:
public interface INetResponseListener { /** * 網(wǎng)絡(luò)請求返回 * @param result */ public void OnRequestComplete(NetResponse result); }
調(diào)用者只要實(shí)現(xiàn)這個interface,異步接收返回結(jié)果即可,返回結(jié)果就是NetResponse對象。
- 常見問題
1. AsyncTask說明
大家都知道AsyncTask是異步的,所以網(wǎng)絡(luò)請求通過AsyncTask來實(shí)現(xiàn),通過AyncTask的好處是輕量級異步,而且可以操作ui線程,比如更新進(jìn)度條等。但AsyncTask也存在以下一些問題:
•task需要在ui線程中創(chuàng)建和啟用,所以AbstractRequester 對象的創(chuàng)建和調(diào)用StartRequest請?jiān)趗i線程中完成
•API 11也就是3.0以后,AsyncTask是排隊(duì)執(zhí)行,所以如果其中一個任務(wù)出現(xiàn)較耗時,其它網(wǎng)絡(luò)請求需要等待;如果你想同步執(zhí)行,要修改execute為executeOnExecutor(但不推薦做這個修改)
2. 權(quán)限
在xml中添加網(wǎng)絡(luò)操作權(quán)限:
<uses-permission android:name="android.permission.INTERNET" />
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開發(fā)中Activity的生命周期及加載模式詳解
這篇文章主要介紹了Android開發(fā)中Activity的生命周期及加載模式詳解的相關(guān)資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下2016-05-05Android編程實(shí)現(xiàn)基于BitMap獲得圖片像素?cái)?shù)據(jù)的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)基于BitMap獲得圖片像素?cái)?shù)據(jù)的方法,對比分析了兩種獲取圖片像素的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11Android?JetPack組件的支持庫Databinding詳解
DataBinding是Google發(fā)布的一個數(shù)據(jù)綁定框架,它能夠讓開發(fā)者減少重復(fù)性非常高的代碼,如findViewById這樣的操作。其核心優(yōu)勢是解決了數(shù)據(jù)分解映射到各個view的問題,在MVVM框架中,實(shí)現(xiàn)的View和Viewmode的雙向數(shù)據(jù)綁定2022-08-08Android Studio 導(dǎo)入開源項(xiàng)目的正確姿勢及注意事項(xiàng)
這篇文章主要介紹了Android Studio 導(dǎo)入開源項(xiàng)目的正確姿勢及注意事項(xiàng),需要的朋友參考下吧2018-03-03

android ListView內(nèi)數(shù)據(jù)的動態(tài)添加與刪除實(shí)例代碼