天天看點

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構

最新版介紹看這裡—————>這是一個使用政策模式和構模組化式設計的網絡請求架構,去看看吧《[傾力之作]android輕量級網絡請求架構MyHttputils2.1.6》

一、能做什麼

你隻需要傳url,JavaBean就可以在回調方法裡面得到想要的結果,你會發現你的代碼裡面沒有了子線程、沒有了handle,鍊式的程式設計使得代碼結構更加清晰。

1.1 功能

  1. 支援get、post請求;
  2. 支援http和https的協定;
  3. 支援設定連接配接、讀取逾時時間(可選);
  4. 支援json格式的請求結果(無論json格式多複雜,都能搞定);
  5. 支援傳入JavaBean對象(解析之後的javabean對象);
  6. 支援回調方法中反應傳入javabean對象,這樣可以在回調方法中直接拿到解析過後的javabean對象;
  7. 支援回調方法中更新UI(是以叫異步請求了)。
說明:java中一切皆對象,這裡的JavaBean對象就是你請求接口之後傳回的json資料所對應的實體。

1.2 使用場景

大部分的網絡請求都是傳回json格式的資料,秉承java中一切皆對象的原則,這個json格式的資料必定對應一個JavaBean。你隻要能通過json格式構造出相應的javabean對象(文章的最後會介紹如何快速構造JavaBean對象),那麼用幾行代碼就可以幫你解析出來。(如果你的項目中不能使用Retrofit,OkHttp那麼你是找對地方了)。是以,隻要請求接口傳回的資料格式是json的都可以用。

備注:目前還不支援檔案上傳和下載下傳,後續将跟進,敬請關注

二、怎麼用

方法一:gradle導入(推薦)最新版本請移步GitHub

方法二:導入arr包(上面方法失敗的話就用這個吧)

進入項目的github首頁,下載下傳該項目,arr檔案就在.\MyHttpUtils\myhttputils1.0\build\outputs\aar檔案夾下面(點選這裡進入github)。你要是嫌麻煩的話點選這裡直接下載下傳arr檔案。更多使用方法請看jcenter.bintray首頁

注意:由于使用到了由于架構中使用到了gson,是以也不需要加入gson的依賴。(如果你的項目中已經有了Gson的依賴請删除)

三、應用舉例

3.1 get請求

下面通過一個查詢ip位址資訊的demo來介紹get方式的使用(先來看運作的效果圖):

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構

上代碼:

/**
     * 擷取IP位址的監聽事件
     *
     * @param view
     */
    public void onGetIP(View view) {
        String url = "http://ip.taobao.com/service/getIpInfo.php?ip=182.254.34.74";//請求的接口
        new MyHttpUtils()
                .url(url)//請求的url
                .setJavaBean(IPBean.class)//設定需要解析成的javabean對象
                .setReadTimeout()//設定讀取逾時時間,不設定的話預設為30s(30000)
                .setConnTimeout()//設定連接配接逾時時間,不設定的話預設5s(5000)
                .onExecute(new CommCallback<IPBean>() {//開始執行異步請求,傳入一個通用回調對象,泛型為傳回的javabean對象
                    @Override
                    public void onSucess(IPBean ipBean) {//成功之後回調
                        KLog.e("測試:" + ipBean.toString());
                        Toast.makeText(MainActivity.this, ipBean.toString(), Toast.LENGTH_SHORT).show();
                    }
                    @Override
                    public void onFailed(String msg) {//失敗時候回調
                        KLog.e(msg);
                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                    }
                });
    }
           

方法及參數說明:

-url():設定請求的接口位址,參數類型為String。(必填)

-setJavaBean():設定解析之後的JavaBean對象,記得加.class。(必填)

-onExecute():設定開始請求(get)接口,請求結果在回調方法中,參數為CommCallback,可加泛型。(必填)

-setReadTimeout():設定讀取逾時時間(預設30s),參數為整型,機關:毫秒。(可選)

-setConnTimeout():設定連接配接逾時時間(預設5s),參數為整型,機關:毫秒。(可選)

3.2 post請求

下面通過一個擷取使用者備注、和跟蹤資訊的例子來說明post的用法(先看效果圖):

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構

上代碼:

public void onGetRemark(View view) {
        String remarkUrl = "http://192.168.1.161:8080/Test/userInfoController/updateUser.action";
        HashMap<String, String> param = new HashMap<>();
        param.put("userid", "7cf6871beeed856df47eb189");
        param.put("uid", "8011bddb58588ab54");
        new MyHttpUtils()
                .url(remarkUrl)
                .addParam(param)
                .setJavaBean(RemarkBean.class)
                .onExecuteByPost(new CommCallback<RemarkBean>() {
                    @Override
                    public void onSucess(RemarkBean remarkBean) {
                        Toast.makeText(MainActivity.this, remarkBean.toString(), Toast.LENGTH_SHORT).show();
                        KLog.e("解析出來的對象為:" + remarkBean.toString());
                    }
                    @Override
                    public void onFailed(String msg) {
                        KLog.e("錯誤消息:" + msg);
                    }
                });
    }
}
           

方法及參數說明:

-url():設定請求的接口位址,參數類型為String。(必填)

-setJavaBean():設定解析之後的JavaBean對象,記得加.class。(必填)

-addParam():設定post請求的參數,參數為hashmap類型。(必填)

-onExecuteByPost():設定開始請求(post)接口,請求結果在回調方法中,參數為CommCallback,可加泛型。(必填)

-setReadTimeout():設定讀取逾時時間(預設30s),參數為整型,機關:毫秒。(可選)

-setConnTimeout():設定連接配接逾時時間(預設5s),參數為整型,機關:毫秒。(可選)

通過上面的兩個例子是不是覺得這個架構很好用,隻需要傳url,javabean就可以在回調方法裡面得到想要的結果,你會發現你的代碼裡面沒有了子線程、沒有了handle,鍊式程式設計使得代碼結構更加清晰。如果對Rxjava,Retrofit,OkHttp熟悉的朋友肯定覺得這種方式似曾相識,的确這種鍊式+回調有很多的好處。

四、如何快速通過json建構javabean對象

推薦一個非常好用的AS插件GsonFormat。(當然,你也可以通過http://www.jsonschema2pojo.org/直接生成javabean對象,不是很喜歡,因為沒有GsonFormat好用)

4.1 什麼是GsonFormt

就是直接将json資料格式轉換為javabean對象的as插件。

4.2 安裝步驟

settings–>Plugins—>輸入GsonFormat—>Browse—>Install—>重新開機as即可

來個圖看看:

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構

4.3 怎麼用GsonFormat

1)、比如你請求接口之後,傳回的json資料是:

{
  "username":"hdl",
  "pwd":"L23LK4J3LJLKJL436LKJKL7LJLGKK4"
}
           

2)、先建立一個與json資料對應類,這個類名随意,在類中使用快捷鍵alt+Insert(右鍵–>Generate也可以)會彈出一個對話框,第一個就是GsonFormat插件,打開之後讓你輸入Json資料,點選确定—>确定即可自動生成。最後實作Serializable 接口即可(為了能更好地測試資料,你最後重寫toString方法)。再來個圖

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構

3)、這樣你就可以得到架構中setJavaBean()中的JavaBean了。你隻需要傳url,javabean就可以在回調方法裡面得到想要的結果,是不是很簡單?。

有人可能會說這是簡單的一個javabean對象,複雜的json怎麼搞?帶json數組的又咋搞。

那我可以負責的告訴你,方法一樣的。隻要你的json格式正确就能生成對應的javabean對象。來看一個複雜的json。(豆瓣Top250的電影,屬性幾十個呢)

下面是請求豆瓣排名第一的電影(隻是一條哦):https://api.douban.com/v2/movie/top250?start=0&count=1

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構

是不是很長很長,用gsonformat管理多長照樣搞定。複制json—>粘貼—>确定—>實作Serializable接口,四步搞定。

《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構《Android網絡請求篇》MyHttpUtils一個非常好用的異步網絡請求架構
溫馨提示:裡面的屬性名千萬不要改哦,必須要跟json資料生成的保持一緻。要擷取list資料,通過類似于new javabean().getData()的方法就可以得到了。

五、封裝思路

使用講完了,來講講怎麼封裝的吧(感興趣的可以下載下傳源碼,共同學習)。封裝過程其實很簡單,用到了三個東西線程、handler、httpurlconnection,回調思想。

5.1 回調思想

其他三個大家都懂,就隻說說回調思想:說白了就是我調用某個方法,成功還是失敗,你總得告訴我一聲(是不是很直白)。來看看架構裡面用到的通用回調對象怎麼定義的。

public interface CommCallback<T> {
    void onSucess(T t);//成功了就調用,傳回的類型得到的類型就是T(傳入的JavaBean對象)
    void onFailed(String msg);//失敗了就調用,接收的就是錯誤資訊。
}
           

就是這麼簡單。

5.2 get請求的封裝

try {
                    URL url = new URL(urlPath);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setReadTimeout(readTimeout);
                    conn.setConnectTimeout(connectTimeout);
                    if (conn.getResponseCode() == ) {
                        InputStream is = conn.getInputStream();
                        int len = ;
                        byte[] buf = new byte[ * ];
                        StringBuilder json = new StringBuilder();
                        while ((len = is.read(buf)) != -) {
                            json.append(new String(buf, , len));
                        }
                        is.close();
                        Message msg = mHanler.obtainMessage();
                        msg.what = WHAT_REQSUCCESS;
                        msg.obj = json.toString();
                        mHanler.sendMessage(msg);
                    } else {
                        mHanler.sendEmptyMessage(WHAT_REQFAILED);
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    mHanler.sendEmptyMessage(WHAT_URLFAILED);
                } catch (IOException e) {
                    mHanler.sendEmptyMessage(WHAT_IOFAILED);
                    e.printStackTrace();
                }
           

這簡直就是标準的HttpurlConnection請求方式嘛。我就不一一說了。post請求類似。

5.3 封裝的經過

來說說為啥要使用HttpUrlConnection來封裝。一方面,它是官方推薦的網絡請求方式,但是請求過程代碼太累贅(看看上面的代碼就知道了),于是就像封裝一下,用幾行代碼就搞定,提高工作效率;還有一個原因就是在我維護的一個項目中,之前的那個人用的是OKHttp2.X開發的,在新增功能的時候不想用okhttp2.X了,聽過有bug。但是更新到okhttp3.X的話要改的又太多。于是我就想到了Retrofit,但是其實Retrofit底層也是用okhttp實作的,雖然導入retrofit依賴的時候不會報錯,但是運作的時候就錯了(估計是包沖突了),于是我又想到了以前用過的vollery和xUtils,額,還是算了,它們封裝的東西太多了,我就簡簡單單的發個網絡請求而已。怎麼辦呢,就隻用httpurlconnection了,直接用這個呢要寫的代碼真的是太備援了,于是就有了這個封裝的網絡請求架構了,基本上可以滿足大部分的網絡請求了,目前還不支援檔案上傳、下載下傳,後續會跟進,敬請關注。

六、下載下傳位址

源碼及demo下載下傳位址:https://github.com/huangdali/MyHttpUtils

歡迎通路我的CDSN部落格首頁(http://blog.csdn.net/qq137722697/),了解更多原創博文。