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也是可以拿到具體的錯誤資料的