1. 程式人生 > >OkGo3.0真實專案使用和二次封裝

OkGo3.0真實專案使用和二次封裝

前言

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

分析

現在的網路框架正常都是使用的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也是可以拿到具體的錯誤資料的