超簡單的okHttpUtils封裝(下)


 

版權聲明:轉載請注明出處:http://blog.csdn.net/piaomiao8179 https://blog.csdn.net/piaomiao8179/article/details/70888901

前言:

上一篇我們講到了基本的Okhttp的封裝,只需要我們在代碼種調用okHttpUtils.getInstance().GET(url, MyCallBack),一句話完事,而且還是鏈式的,只需要在MyCallBack中處理返回的Response即可,是不是感覺很爽,不要着急,接下來會讓你更爽,請自行准備紙巾,條件允許的話也可以為你的寶貝充上氣。沒有看過上篇文章的,最好看一下,點擊即可跳轉: 超簡單的okhttp封裝工具類(上)
好了,廢話不多說,進入正題,本篇主要思想是,通過上篇的封裝,聯網成功后,返回的是Response對象,我們平時聯網需要的結果是一個JavaBean或者一個集合,泛型為JavaBean。那么,接下來就是實現直接返回帶泛型的集合,而不是還需要我們處理的Response。

MyCallBack接口的改寫

首先,在MyCallBack后面加上泛型,到時候需要實例化這個callback時候,自然的把我們需要轉換成的JavaBean以泛型的形式傳遞過去。
本篇采用Gson進行Response的json轉換,所以需要根據泛型獲取Type對象。獲取方法如下:

//根據T獲取Type
static Type getSuperclassTypeParameter(Class<?> subclass)
{
    Type superclass = subclass.getGenericSuperclass();
    if (superclass instanceof Class)
    {
        throw new RuntimeException("Missing type parameter.");
    }
    ParameterizedType parameterized = (ParameterizedType) superclass;
    return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

我們原來定義的MyCallBack為接口,此時需要改寫成抽象類,因為要用到構造方法進行構造Type對象。具體代碼如下:

public abstract class MyCallBack<T> {


public  Type mType;

static Type getSuperclassTypeParameter(Class<?> subclass)
{
    Type superclass = subclass.getGenericSuperclass();
    if (superclass instanceof Class)
    {
        throw new RuntimeException("Missing type parameter.");
    }
    ParameterizedType parameterized = (ParameterizedType) superclass;
    return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}

public MyCallBack() {
    mType = getSuperclassTypeParameter(getClass());
}

public abstract void onLoadingBefore(Request request);
//第二個參數為傳入的泛型,也就是說返回的結果直接就是我們需要的類型
public abstract void onSuccess(Response response, T result);

public abstract void onFailure(Request request, Exception e);

public abstract void onError(Response response);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

OkHttpUtils工具類的改寫

我們主要是改寫Response返回的地方,也就是聯網邏輯這一塊,即requestNetWork()方法。具體請看代碼實現,注釋很清晰。

private void requestNetWork(Request request, MyCallBack<Object> callBack) {

    /**
     * 處理連網邏輯,此處只處理異步操作enqueue
     */
    callBack.onLoadingBefore(request);

    mOkHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            mHandler.post(() -> callBack.onFailure(request, e));

        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {

                String resultStr = response.body().string();
                if (callBack.mType == String.class) {
                    // 如果想要返回字符串 直接返回就行
                    mHandler.post(() -> callBack.onSuccess(response, resultStr));
                } else {
                    // 需要返回解析好的javaBean集合
                    try {
                        // 此處暫時寫成object,使用時返回具體的帶泛型的集合
                        Object obj = mGson.fromJson(resultStr, callBack.mType);
                        mHandler.post(() -> callBack.onSuccess(response, obj));
                    } catch (Exception e) {
                        // 解析錯誤時
                        mHandler.post(() -> callBack.onError(response));
                    }

                }

            } else {
                mHandler.post(() -> callBack.onError(response));
            }
        }
    });


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

界面聯網具體操作

具體使用方法如下:在Fragment的OnCreatView方法中寫的邏輯,根據需求自己選擇在哪里聯網,此處只是測試,不建議在這個方法中處理。會阻塞界面顯示。

private String url = "http://222.133.11.150:8402/EnvService/Version/CheckVersion?imei=860806029044186&version=111";

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    OkHttpUtils.getInstance().Get(url, new MyCallBack<ceshiBean>() {

        @Override
        public void onLoadingBefore(Request request) {

        }

        @Override
        public void onSuccess(Response response, ceshiBean result) {
            System.out.println("-----" + result.getStrApkUrl());
        }

        @Override
        public void onFailure(Request request, Exception e) {

        }

        @Override
        public void onError(Response response) {

        }
    });

    return  inflater.inflate(R.layout.fragment_home,container,false);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

ceshiBean的代碼

這是我們根據接口寫的javaBean對象
public class ceshiBean {

/**
 * StrApkUrl : http://222.133.11.150:8402/EnvService/versioninfo/EnvDS_DZ.apk
 * StrUpdateDate : 2017.4.18
 * StrUpdateFlag : 0
 * StrUpdateLog :
 1.城市空氣模塊,新增加鄉鎮站、邊界站、農村站交通站。

 * StrVersionCode : 110
 * StrVersionName : 1.1.0
 */

private String StrApkUrl;
private String StrUpdateDate;
private String StrUpdateFlag;
private String StrUpdateLog;
private String StrVersionCode;
private String StrVersionName;

public String getStrApkUrl() {
    return StrApkUrl;
}

public void setStrApkUrl(String StrApkUrl) {
    this.StrApkUrl = StrApkUrl;
}

public String getStrUpdateDate() {
    return StrUpdateDate;
}

public void setStrUpdateDate(String StrUpdateDate) {
    this.StrUpdateDate = StrUpdateDate;
}

public String getStrUpdateFlag() {
    return StrUpdateFlag;
}

public void setStrUpdateFlag(String StrUpdateFlag) {
    this.StrUpdateFlag = StrUpdateFlag;
}

public String getStrUpdateLog() {
    return StrUpdateLog;
}

public void setStrUpdateLog(String StrUpdateLog) {
    this.StrUpdateLog = StrUpdateLog;
}

public String getStrVersionCode() {
    return StrVersionCode;
}

public void setStrVersionCode(String StrVersionCode) {
    this.StrVersionCode = StrVersionCode;
}

public String getStrVersionName() {
    return StrVersionName;
}

public void setStrVersionName(String StrVersionName) {
    this.StrVersionName = StrVersionName;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

總結

到此為止,已經實現了簡化邏輯,只需要調用方法時候傳入泛型javaBean即可,就能直接獲取數據了。

可能有的小伙伴會說,這只是單個javaBean對象的解析,如果我們接口返回的是好對個javaBean的集合,怎么辦,so easy,只需要把泛型寫成List的形式就好了,直接給你返回一個集合數據集,太爽了。

當然,還有更方便的寫法,你可以再次自定義一個具體的CallBack繼承MyCallBack,實現里面的方法,在聯網開始前顯示加載對話框,解析結束隱藏對話框,處理相應的邏輯。那么在前台界面只需要處理你自己的數據就可以了。

聲明:本文實現思路是參考IVan的封裝思路,只做學習用途。

OkHttpUtils改進后的源碼


public class OkHttpUtils { /** * 網絡訪問要求singleton */ private static OkHttpUtils instance; // 必須要用的okhttpclient實例,在構造器中實例化保證單一實例 private OkHttpClient mOkHttpClient; public static final MediaType JSON = MediaType. parse("application/json; charset=utf-8"); private Handler mHandler; private Gson mGson; private OkHttpUtils() { /** * okHttp3中超時方法移植到Builder中 */ mOkHttpClient = (new OkHttpClient()).newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); mHandler = new Handler(Looper.getMainLooper()); mGson = new Gson(); } public static OkHttpUtils getInstance() { if (instance == null) { synchronized (OkHttpUtils.class) { if (instance == null) { instance = new OkHttpUtils(); } } } return instance; } /** * 對外提供的Get方法訪問 * @param url * @param callBack */ public void Get(String url, MyCallBack callBack) { /** * 通過url和GET方式構建Request */ Request request = bulidRequestForGet(url); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * 對外提供的Post方法訪問 * @param url * @param parms: 提交內容為表單數據 * @param callBack */ public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) { /** * 通過url和POST方式構建Request */ Request request = bulidRequestForPostByForm(url, parms); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * 對外提供的Post方法訪問 * @param url * @param json: 提交內容為json數據 * @param callBack */ public void PostWithJson(String url, String json, MyCallBack callBack) { /** * 通過url和POST方式構建Request */ Request request = bulidRequestForPostByJson(url, json); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * POST方式構建Request {json} * @param url * @param json * @return */ private Request bulidRequestForPostByJson(String url, String json) { RequestBody body = RequestBody.create(JSON, json); return new Request.Builder() .url(url) .post(body) .build(); } /** * POST方式構建Request {Form} * @param url * @param parms * @return */ private Request bulidRequestForPostByForm(String url, Map<String, String> parms) { FormBody.Builder builder = new FormBody.Builder(); if (parms != null) { for (Map.Entry<String, String> entry : parms.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } FormBody body = builder.build(); return new Request.Builder() .url(url) .post(body) .build(); } /** * GET方式構建Request * @param url * @return */ private Request bulidRequestForGet(String url) { return new Request.Builder() .url(url) .get() .build(); } private void requestNetWork(Request request, MyCallBack<Object> callBack) { /** * 處理連網邏輯,此處只處理異步操作enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { mHandler.post(() -> callBack.onFailure(request, e)); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String resultStr = response.body().string(); if (callBack.mType == String.class) { // 如果想要返回字符串 直接返回就行 mHandler.post(() -> callBack.onSuccess(response, resultStr)); } else { // 需要返回解析好的javaBean集合 try { // 此處暫時寫成object,使用時返回具體的帶泛型的集合 Object obj = mGson.fromJson(resultStr, callBack.mType); mHandler.post(() -> callBack.onSuccess(response, obj)); } catch (Exception e) { // 解析錯誤時 mHandler.post(() -> callBack.onError(response)); } } } else { mHandler.post(() -> callBack.onError(response)); } } }); } } 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM