上一篇中我們介紹了OkHttp3.0框架的基本使用方法痪伦,這一篇我們學習一下Android的另外一個網(wǎng)絡(luò)請求框架——AsyncHttpClient框架吃环。Asynchttpclient框架是一個開源的異步網(wǎng)絡(luò)請求框架氯窍,所有的網(wǎng)絡(luò)都在Android的非UI線程中漏益,通過回調(diào)方法處理請求結(jié)果墩邀,無論是向網(wǎng)絡(luò)請求數(shù)據(jù)還是上傳數(shù)據(jù)都非常方便穆桂,而且這個框架非常體積非常小宫盔,只有90K左右的大小,我們可以輕松使用它享完,下面我們介紹一下這個框架:
概述
Asynchttpclient框架有如下的特征:
處理異步Http請求灼芭,并通過匿名內(nèi)部類處理回調(diào)結(jié)果
Http異步請求均位于非UI線程,不會阻塞UI操作
通過線程池處理并發(fā)請求處理文件上傳般又、下載,響應(yīng)結(jié)果自動打包JSON格式
自動處理連接斷開時請求重連
永久的cookie保存彼绷,內(nèi)部實現(xiàn)用的是Android的SharedPreferences
通過BaseJsonHttpResponseHandler和各種json庫集成
支持SAX解析器
支持各種語言和content編碼,不僅僅是UTF-8
自動的gzip響應(yīng)解碼
內(nèi)置多種形式的響應(yīng)解析茴迁,有原生的字節(jié)流寄悯,string,json對象堕义,甚至可以將response寫到文件中
這里只是簡單的介紹一下猜旬,具體需要實現(xiàn)細節(jié)需要我們在開發(fā)中實際去體會。
我們來學習一下Asynchttpclient里面的具體的類:
AsyncHttpRequest類:繼承自Runnabler倦卖,被submit至線程池執(zhí)行網(wǎng)絡(luò)請求并發(fā)送start洒擦,success等消息
AsyncHttpResponseHandler類:接收請求結(jié)果,一般重寫onSuccess及onFailure接收請求成功或失敗的消息怕膛,還有onStart熟嫩,onFinish等消息
TextHttpResponseHandler類:繼承自AsyncHttpResponseHandler,只是重寫了AsyncHttpResponseHandler的onSuccess和onFailure方法褐捻,將請求結(jié)果由byte數(shù)組轉(zhuǎn)換為String
JsonHttpResponseHandler類:繼承自TextHttpResponseHandler掸茅,同樣是重寫onSuccess和onFailure方法椅邓,將請求結(jié)果由String轉(zhuǎn)換為JSONObject或JSONArray
BaseJsonHttpResponseHandler類:繼承自TextHttpResponseHandler,是一個泛型類昧狮,提供了parseResponse方法景馁,子類需要提供實現(xiàn),將請求結(jié)果解析成需要的類型陵且,子類可以靈活地使用解析方法,可以直接原始解析个束,使用gson等
RequestParams類:請求參數(shù)慕购,可以添加普通的字符串參數(shù),并可添加File茬底,InputStream上傳文件
AsyncHttpClient類:核心類沪悲,使用HttpClient執(zhí)行網(wǎng)絡(luò)請求,提供了get阱表,put殿如,post,delete最爬,head等請求方法涉馁,使用起來很簡單,只需以url及RequestParams調(diào)用相應(yīng)的方法即可爱致,還可以選擇性地傳入Context烤送,用于取消Content相關(guān)的請求,同時必須提供ResponseHandlerInterface(AsyncHttpResponseHandler繼承自ResponseHandlerInterface)的實現(xiàn)類糠悯,一般為AsyncHttpResponseHandler的子類帮坚,AsyncHttpClient內(nèi)部有一個線程池,當使用AsyncHttpClient執(zhí)行網(wǎng)絡(luò)請求時互艾,最終都會調(diào)用sendRequest方法试和,在這個方法內(nèi)部將請求參數(shù)封裝成AsyncHttpRequest(繼承自Runnable)交由內(nèi)部的線程池執(zhí)行
SyncHttpClient類:繼承自AsyncHttpClient,同步執(zhí)行網(wǎng)絡(luò)請求纫普,AsyncHttpClient把請求封裝成AsyncHttpRequest后提交至線程池阅悍,SyncHttpClient把請求封裝成AsyncHttpRequest后直接調(diào)用它的run方法
這里就不介紹里面的方法了,具體的可以去Github看一下源碼:https://github.com/loopj/android-async-http
或者可以看一下API:https://loopj.com/android-async-http/doc/
再簡單介紹一下Asynchttpclient框架的請求流程:
首先調(diào)用AsyncHttpClient的get或post等方法發(fā)起網(wǎng)絡(luò)請求
所有的請求都走了sendRequest昨稼,在sendRequest中把請求封裝為了AsyncHttpRequest溉箕,并添加到線程池執(zhí)行
當請求被執(zhí)行時(即AsyncHttpRequest的run方法),執(zhí)行AsyncHttpRequest的makeRequestWithRetries方法執(zhí)行實際的請求悦昵,當請求失敗時可以重試肴茄。并在請求開始,結(jié)束但指,成功或失敗時向請求時傳的ResponseHandlerInterface實例發(fā)送消息
基本上使用的都是AsyncHttpResponseHandler的子類寡痰,調(diào)用其onStart抗楔,onSuccess等方法返回請求結(jié)果
關(guān)于Asynchttpclient就簡單介紹到這里,下面介紹一下Asynchttpclient的具體使用
使用
Asynchttpclient框架的使用步驟基本是:
創(chuàng)建一個AsyncHttpClient對象
通過RequestParams對象設(shè)置請求參數(shù)拦坠,這個是可選擇的
調(diào)用AsyncHttpClient對象里面的方法连躏,實現(xiàn)請求或者上傳數(shù)據(jù)。這里需要實現(xiàn)內(nèi)部類回調(diào)贞滨,框架自己有實現(xiàn)有入热,不需要我們自己手動實現(xiàn),我們只需要調(diào)用即可晓铆。
如果是在Android Studio中使用勺良,需要在gradle中添加:
compile 'com.loopj.android:android-async-http:1.4.9'
如果是Eclipse的話需要去GitHub或者官網(wǎng)下載相應(yīng)版本的JAR吧,GitHub地址在上文中有給出骄噪,下面是Asynchttpclient的官網(wǎng):http://loopj.com/android-async-http/
下面看一下具體的代碼:
AsyncHttpClient client = new AsyncHttpClient();
client.get("https://www.google.com", new AsyncHttpResponseHandler() {
@Override
public void onStart() {
// called before request is started
}
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
@Override
public void onRetry(int retryNo) {
// called when request is retried
}
});
這里是Get請求的寫法尚困,官方推薦我們使用靜態(tài)的寫法:
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;
}
}
這樣方便我們使用。
下面我們使用這個框架實現(xiàn)GET請求链蕊、POST請求事甜、文件上傳、文件下載這四個功能滔韵,這里沒有實現(xiàn)保存Cookie的功能逻谦,有需要的可以擴展實現(xiàn):
實現(xiàn)GET請求
我們先看一下具體實現(xiàn)的代碼:
AsyncHttpUtils.get(UrlUtils.REQUEST_URL + UrlUtils.URL_KEY, null, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
Log.i(TAG, getResources().getString(R.string.req_success));
Log.i(TAG, "======================================================================");
Log.i(TAG, response.toString());
Log.i(TAG, "======================================================================");
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
Log.i(TAG, getResources().getString(R.string.req_failed));
}
});
這樣就可以實現(xiàn)一個GET請求,請求是在非UI線程中陪蜻,有請求成功的回調(diào)和請求失敗的回調(diào)跨跨,我們更新UI需要通過發(fā)消息或者其它方式實現(xiàn),不能再請求成功的回調(diào)方法里面直接更新UI囱皿。其中RequestParams是可以選擇的勇婴,沒有請求參數(shù)可以直接設(shè)置為null。非常簡單嘱腥,就不在做過多的介紹了耕渴。
實現(xiàn)POST請求
我們還是先看一下具體的代碼:
RequestParams requestParams = new RequestParams();
requestParams.put("username", "Devin");
requestParams.put("password", "Devin");
AsyncHttpUtils.post(UrlUtils.POST_URL, requestParams, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Log.i(TAG, getResources().getString(R.string.req_success));
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.i(TAG, getResources().getString(R.string.req_failed));
}
});
POST請求需要上傳一些參數(shù),框架提供了設(shè)置參數(shù)的類RequestParams齿兔,其中橱脸,RequestParams類似于Map,是鍵值對的形式分苇,添加請求參數(shù)有三種方式:
第一種就是像我上面代碼一樣添诉,創(chuàng)建一個空的RequestParams對象,然后通過put方法將參數(shù)寫入医寿;
第二種則是創(chuàng)建的時候就直接添加栏赴,例如:
RequestParams params = new RequestParams("single", "value");
第三種是將參數(shù)寫入一個Map中,然后將Map賦給RequestParams靖秩,例如:
HashMap<String, String> paramMap = new HashMap<String, String>();
paramMap.put("key", "value");
RequestParams params = new RequestParams(paramMap);
這三種方式無論哪一種都可以實現(xiàn)封裝請求參數(shù)须眷。
實現(xiàn)文件上傳
使用Asynchttpclient實現(xiàn)文件上傳也非常簡單竖瘾,我們先看一下代碼:
RequestParams requestParams = new RequestParams();
File file = new File("/sdcard/okhttp-3.4.1.jar");
try {
requestParams.put("file", file);
AsyncHttpUtils.post(UrlUtils.UPLOAD_URL, requestParams, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Log.i(TAG, getResources().getString(R.string.req_success));
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.i(TAG, getResources().getString(R.string.req_failed));
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
}
可以看到,這里文件上傳是將文件封裝到RequestParams中的花颗,Asynchttpclient框架提供的封裝文件到RequestParams中有三種方法捕传,分別是:
第一種是將文件轉(zhuǎn)成流的形式封裝到RequestParams中,例如:
InputStream myInputStream = blah;
RequestParams params = new RequestParams();
params.put("secret_passwords", myInputStream, "passwords.txt");
第二種就是像上面的代碼一樣扩劝,將文件直接封裝到RequestParams中
第三種是將文件轉(zhuǎn)成二進制數(shù)組的形式庸论,例如:
byte[] myByteArray = blah;
RequestParams params = new RequestParams();
params.put("soundtrack", new ByteArrayInputStream(myByteArray), "she-wolf.mp3");
這三種方法無論哪一種都可以實現(xiàn)封裝文件到RequestParams中,然后調(diào)用AsyncHttpClient對象中的方法實現(xiàn)上傳棒呛,具體使用哪一種看個人喜歡了聂示。
實現(xiàn)文件下載
使用Asynchttpclient框架實現(xiàn)文件下載也非常簡單,我們先看一下代碼:
AsyncHttpUtils.download(UrlUtils.DOWNLOAD_URL, null, new FileAsyncHttpResponseHandler(getActivity()) {
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) {
Log.i(TAG, getResources().getString(R.string.req_failed));
}
@Override
public void onSuccess(int statusCode, Header[] headers, File file) {
Log.i(TAG, getResources().getString(R.string.req_success));
}
});
實現(xiàn)文件下載条霜,回調(diào)選擇的就是FileAsyncHttpResponseHandler這個Asynchttpclient框架提供的類催什,這可以非常方便的實現(xiàn)文件的下載涵亏。
關(guān)于Asynchttpclient框架就簡單介紹到這里了宰睡,還有保存Cookie這個功能沒有實現(xiàn),不過實現(xiàn)也非常簡單气筋,不懂得可以看一下官方的文檔拆内,官網(wǎng)地址上文中有給出了。
文中Demo已經(jīng)上傳到GitHub中宠默,有興趣的可以去了解一下:https://github.com/Devin1102/AndroidFrameDemo
最后麸恍,歡迎留言交流學習!