OkGo3.0真實項目使用和二次封裝

前言

之前使用okhttputil,由於鴻洋的該框架並未對於回調數據進行過度處理,callback需要自定義處理,所以在項目使用時對其進行了封裝,後來發現OkGo對於Callback進行了封裝,自己的封裝Callback和OkGo的有些相似,然後在新的項目中就使用基於OkGo二次封裝的網絡請求框架了,這裏主要介紹OkGo的基於MVC下的二次封裝和使用

本文案例的項目地址 https://github.com/caixingcun/OkGoDemo

OkGo地址 https://github.com/jeasonlzy/okhttp-OkGo/wiki
OkHttpUtil 地址 https://github.com/hongyangAndroid/okhttputils

分析

現在的網絡框架正常都是使用的json從後臺獲取數據,這裏保存RESTful風格
這裏需要首先跟後臺約定好傳遞數據的格式
常規數據格式

{
    "Code":100,
    "Msg":"請求成功",
    "Result":{
        "Name":"老王"
    }
}

常規錯誤數據格式

{
    "Code":101,
    "Msg":"請求失敗",
}

數組數據

{
    "Code":100,
    "Msg":"請求成功",
    "Result":[
        {
            "Name":"老王",
            "Age":23
        },
        {
            "Name":"老李",
            "Age":25
        }
    ]
}

數組請求爲空
{
“Code”:100,
“Msg”:”請求成功”,
“Result”:[]
}

OkGo的集成

1.添加依賴
compile ‘com.readystatesoftware.chuck:library:1.0.4’
compile ‘com.readystatesoftware.chuck:library:1.0.4’
2.App中初始化
有特定需求的可以按okgo文檔配置

      OkGo.getInstance().init(this);

3.下載OkGo案例
這裏寫圖片描述

將demo下callback中的內容複製進自己的項目
這部分是作者編寫的可供修改的框架部分
這裏寫圖片描述
有報錯基本就是類不存,或者重寫import
把相關類複製進來

可以看一下當前複製進來的主要幾個類
Convert.java 轉換
JsonConvert.java 帶泛型轉換
JsonCallback.java 泛型轉換回調

LzyResponse.java 實體類
SimpleResponse.java

顧名思義 也可以看出這些類的大概意思
基本上Convert就是基本的Gson轉換
這裏寫圖片描述

JsonConvert就是再上面的基礎上對於網絡請求數據進行了初步處理
這裏已經在分析返回錯誤碼
也就是我們最上面定義的{“Code”:101,”Msg”:”“}
這裏寫圖片描述
我們來看一下作者的轉換類 LzyResponse.java
這裏寫圖片描述
基本格式實際上是跟我們統一的

再看一下JsonCallback.java
應該是對於傳遞的泛型進行分類型處理
這裏寫圖片描述
這裏寫圖片描述

OkGo的修改

我這裏先使用node.js創建一個本地簡易網絡訪問服務器
創建一組json請求數據
這裏寫圖片描述

        OkGo.<String>get("http://192.168.1.79:3000/simplerequest")
                .execute(new StringCallback(){
                    @Override
                    public void onSuccess(Response<String> response) {
                        tv.setText(response.body());
                    }
                });

注意上面的是大寫的Code
下面添加一串跟OkGo中Lzy相同的數據結構,並請求

這裏寫圖片描述
代碼

      OkGo.<SimpleResponse>get("http://192.168.1.79:3000/okgoget")
                .execute(new JsonCallback<SimpleResponse>() {
                    @Override
                    public void onSuccess(Response<SimpleResponse> response) {
                        tv.setText(response.body().msg);
                    }
                });

整改開始,就是將作者所給框架的code msg修改爲跟我們後臺約定一樣的格式
改了LzyResponse和SimpleResponse,JsonConvert就可以了,很快
再來通過作者的二次框架來訪問大寫Code Msg

這裏寫圖片描述
基本上能用了

但是要知道爲什麼自己要進行二次封裝網絡框架
正常的StringCallback也可以進行網絡請求,就是因爲方便
這裏需要使用LzyResponse
然後對於JsonConvert和JsonCallback進行整改

當我們使用LzyRespose接收數據時,會發現我們拿不到我們的數據,在Callback回調中
數據

{"Code":104,"Msg":"授權無效"}

代碼

     OkGo.<LzyResponse<Object>>get("http://192.168.1.79:3000/okgo104")
                .execute(new JsonCallback<LzyResponse<Object>>(){
                    @Override
                    public void onSuccess(Response<LzyResponse<Object>> response) {
                        tv.setText(response.body().Msg+response.body().Code);
                    }
              });

在訪問後臺總會發生各種問題,尤其時身份問題
還有各種錯誤,這些東西需要統一處理

看下JsonConvert的源碼

                int code = lzyResponse.Code;
                //這裏的0是以下意思
                //一般來說服務器會和客戶端約定一個數表示成功,其餘的表示失敗,這裏根據實際情況修改
                if (code == 0) {
                    //noinspection unchecked
                    return (T) lzyResponse;
                } else if (code == 104) {
                    throw new IllegalStateException("用戶授權信息無效");
                } else if (code == 105) {
                    throw new IllegalStateException("用戶收取信息已過期");
                } else {
                    //直接將服務端的錯誤信息拋出,onError中可以獲取
                    throw new IllegalStateException("錯誤代碼:" + code + ",錯誤信息:" + lzyResponse.Msg);
                }

我們在這裏只需要將和後臺約定的Code狀況都添加進來
也可以像我之前的代碼
拋出自定義異常 然後統一到onError中處理

         int code = responseBean.Code;
                String msg = responseBean.Msg;
                //這裏的0是以下意思
                //一般來說服務器會和客戶端約定一個數表示成功,其餘的表示失敗,這裏根據實際情況修改
                //這裏的異常會拋到 JsonCallback中 的onError
                if (code == 0 || code == 103) {
                    //noinspection unchecked
                       return (T) responseBean;
                } else {
                    throw new MyException("{\"Code\":"+code+",\"Msg\":\""+msg+"\"}");
                }

在JsonCallback中重寫onError進行異常處理
需要注意onError回調中response.code()是網絡請求的code
不是我們數據中的code

        if (code == 100) {
                    return (T) lzyResponse;
                } else {
                    throw new MyException("{\"Code\":"+code+",\"Msg\":\""+msg+"\"}");
                }

MyException

public class MyException extends IllegalStateException {

    private LzyResponse errorBean;

    public MyException(String s) {
        super(s);
        errorBean = new Gson().fromJson(s, LzyResponse.class);
    }

    public LzyResponse getErrorBean() {
        return errorBean;
    }
}

JsonCallback中 onError

    @Override
    public void onError(com.lzy.okgo.model.Response<T> response) {
        super.onError(response);
        int code = response.code();
        if (code == 404) {
            Log.d("JsonCallback", "404 當前鏈接不存在");
        }
        if (response.getException() instanceof SocketTimeoutException) {
            Log.d("JsonCallback", "請求超時");
        } else if (response.getException() instanceof SocketException) {
            Log.d("JsonCallback", "服務器異常");
        } else if (response.getException() instanceof MyException) {
            switch (((MyException) response.getException()).getErrorBean().Code) {
                case 107: //約定的身份表示過期
                    //重登錄
                    break;
            }

        }
    }

對於回調封裝到這裏就結束了

外部調用簡單封裝

public class OkGoUtil {
    public static <T> void getRequets(String url, Object tag, Map<String, String> map, JsonCallback<T> callback) {
        // TODO: 2017/10/13  加密 時間戳等 請求日誌打印
        Log.d("OkGoUtil", "method get");
        OkGo.<T>get(url)
                .tag(tag)
                .params(map)
                .execute(callback);
    }
    public static <T> void postRequest(String url, Object tag, Map<String, String> map, JsonCallback<T> callback) {
        // TODO: 2017/10/13  加密 時間戳等 請求日誌打印
        Log.d("OkGoUtil", "method post");
        OkGo.<T>post(url)
                .tag(tag)
                .params(map)
                .execute(callback);
    }
}

最後

來看一下調用情況

接口
http://localhost:3000/api/post
數據
{"Code":100,
"Msg":"請求成功",
"Result":{"name":"老王","hobby":"愛吃雞"}
}

新建數據bean

public class SimpleBean {
    /**
     * name : 老王
     * habby : 吃雞
     */

    private String name;
    private String habby;

}

get set方法這裏不貼

請求

      OkGoUtil.getRequets("http://192.168.1.79:3000/okgo_get", this, new HashMap<String, String>(), new JsonCallback<LzyResponse<SimpleBean>>() {
            @Override
            public void onSuccess(Response<LzyResponse<SimpleBean>> response) {
                tv.setText(response.body().Result.getName() + "-" + response.body().Result.getHabby());
            }
        });

最終結果
這裏寫圖片描述

好了封裝完畢

之後每次使用 只需要將Result中數據bean創建出來
其他所有異常 在與後臺約定好後通過Code 在JsonCallback中的onError中進行處理即可

在onSuccess中只處理 Code = 100的正常情況

如果有需要在主線程需要做什麼特殊處理
在調用時的Callback中重寫onError也是可以拿到具體的錯誤數據的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章