Android框架學習筆記02AndroidAsycHttp框架

上一篇中我們介紹了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框架的請求流程:

  1. 首先調(diào)用AsyncHttpClient的get或post等方法發(fā)起網(wǎng)絡(luò)請求

  2. 所有的請求都走了sendRequest昨稼,在sendRequest中把請求封裝為了AsyncHttpRequest溉箕,并添加到線程池執(zhí)行

  3. 當請求被執(zhí)行時(即AsyncHttpRequest的run方法),執(zhí)行AsyncHttpRequest的makeRequestWithRetries方法執(zhí)行實際的請求悦昵,當請求失敗時可以重試肴茄。并在請求開始,結(jié)束但指,成功或失敗時向請求時傳的ResponseHandlerInterface實例發(fā)送消息

  4. 基本上使用的都是AsyncHttpResponseHandler的子類寡痰,調(diào)用其onStart抗楔,onSuccess等方法返回請求結(jié)果

關(guān)于Asynchttpclient就簡單介紹到這里,下面介紹一下Asynchttpclient的具體使用

使用

Asynchttpclient框架的使用步驟基本是:

  1. 創(chuàng)建一個AsyncHttpClient對象

  2. 通過RequestParams對象設(shè)置請求參數(shù)拦坠,這個是可選擇的

  3. 調(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

最后麸恍,歡迎留言交流學習!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搀矫,一起剝皮案震驚了整個濱河市抹沪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓤球,老刑警劉巖融欧,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異卦羡,居然都是意外死亡噪馏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門绿饵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來欠肾,“玉大人,你說我怎么就攤上這事拟赊〈烫遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵吸祟,是天一觀的道長虏肾。 經(jīng)常有香客問我廓啊,道長,這世上最難降的妖魔是什么封豪? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任谴轮,我火速辦了婚禮,結(jié)果婚禮上吹埠,老公的妹妹穿的比我還像新娘第步。我一直安慰自己,他們只是感情好缘琅,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布粘都。 她就那樣靜靜地躺著,像睡著了一般刷袍。 火紅的嫁衣襯著肌膚如雪翩隧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天呻纹,我揣著相機與錄音堆生,去河邊找鬼。 笑死雷酪,一個胖子當著我的面吹牛淑仆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哥力,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蔗怠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吩跋?” 一聲冷哼從身側(cè)響起寞射,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锌钮,沒想到半個月后桥温,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡轧粟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年策治,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兰吟。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡通惫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出混蔼,到底是詐尸還是另有隱情履腋,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站遵湖,受9級特大地震影響悔政,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜延旧,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一谋国、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧迁沫,春花似錦芦瘾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挺智,卻和暖如春祷愉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赦颇。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工二鳄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沐扳。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓泥从,卻偏偏與公主長得像句占,于是被迫代替她去往敵國和親沪摄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,498評論 25 707
  • 從三月份找實習到現(xiàn)在纱烘,面了一些公司杨拐,掛了不少,但最終還是拿到小米擂啥、百度哄陶、阿里、京東哺壶、新浪屋吨、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,184評論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法山宾,類相關(guān)的語法至扰,內(nèi)部類的語法,繼承相關(guān)的語法资锰,異常的語法敢课,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • 獨立,我最近一直在想的問題。覺得有點懂的直秆,經(jīng)濟的獨立只是表層的東西濒募,其實最重要的是心理上和精神上,所謂自己的內(nèi)心擁...
    WoodSage閱讀 230評論 0 0
  • 把美好的祝福送給親愛的家人們一天好心情圾结,每天更深的了解功課瑰剃,更多的活在功課中!理解功課沒有重點筝野,活出功課沒有盡頭培他!...
    人間講堂閱讀 355評論 0 0