OkHttp框架二次封裝,post json格式的參數(下)

沒看過上篇的,建議先看上篇,傳送門:http://blog.csdn.net/black_dreamer/article/details/53068620

響應數據的格式

服務器響應的數據,結構也大都固定,比如:

{
"result": {
    "total": 0,
    "data": {
        "uid": 9527,
        "token": "xxxxxxxxxxxxx",
        "username": "xxxxx"
    }
},
"status": 200
}

上面的響應裏,基本上兩個字段是不變的,result字段和status字段,result裏面的字段也相對固定,可能列表數據和單條數據會有不同。

封裝響應

請求封裝的主要內容在TPostJsonBuilder.java裏,將參數拼接轉換,而響應的封裝,主要是解析服務器返回的響應數據,解析成實體類,然後方便我們取裏面的字段。

這裏我們可以先寫一個最外層的結果類,用來接收result和status兩個字段:

TOkHttpResponse.java

public class TOkHttpResponse<T> {


@SerializedName("result")
private T result;

@SerializedName("status")
private int status;

//get and set 方法,略...

}

很簡單,裏面只有兩個成員變量,一個是泛型的result,一個是status。

然後要怎麼用到這個TOkHttpResponse呢?
答案是新建TBaseCallback類繼承自Callback:

TBaseCallback.java

public abstract class TBaseCallback<T> extends Callback<TOkHttpResponse<T>> {

public TBaseCallback() {

}

@Override
public TOkHttpResponse<T> parseNetworkResponse(Response response, int id) throws Exception {

    String str = response.body().string();

    TOkHttpResponse<T> res = new Gson().fromJson(str,new TypeToken<TOkHttpResponse<T>>(){}.getType()) ;
    return res;
}

@Override
public void onError(Call call, Exception e, int id) {
    Log.e("test","e: " + e.toString()) ;
}
}

這個類裏,通過parseNetworkResponse方法,得到response.body().string(),然後轉換成TOkHttpResponse對象並返回。這樣一來,在TBaseCallback的子類的onResponse方法裏,就能得到TOkHttpResponse類型的結果了。

舉個栗子:

針對上面的result字段

"result": {
    "total": 0,
    "data": {
    "uid": 9527,
    "token": "xxxxxxxxxxxxx",
    "username": "xxxxx"
}

裏面字段始終都是total和data,但是data可能是Object ,也可能是array,這裏是object,所以我們給result也建一個基本類,裏面是total和data兩個字段:

TBaseDataResult.java

public class TBaseDataResult<T> {

int total ;

T data;

//get and set 方法,略...
}

在使用的時候,只需要這麼做(headM是請求頭裏的一個字段,pri_args是參數的一部分):

TBaseApi.createPostRequest(headM, pri_args, new TBaseCallback<TBaseDataResult>() {
        @Override
        public void onResponse(TOkHttpResponse<TBaseDataResult> response, int i) {
            TBaseDataResult result = response.getResult() ;
            int total = result.getTotal() ;
            Object data = result.getData() ;
        }
    });

這樣total和data兩個字段都可以輕鬆得到了,如果想繼續解析data,那麼可以再新建個bean對象:

TLogin.java

public class TLogin {
    int uid ;
    String token ;
    String username ;

    ...
}

使用時放進去:

 TBaseApi.createPostRequest(headM, pri_args, new TBaseCallback<TBaseDataResult<TLogin>>() {
        @Override
        public void onResponse(TOkHttpResponse<TBaseDataResult<TLogin>> response, int id) {

            if (response.getStatus() == 200) {

                JsonElement j = new Gson().toJsonTree(response.getResult()) ;
                TBaseDataResult<TLogin> result = new Gson().fromJson(j,new TypeToken<TBaseDataResult<TLogin>>(){}.getType()) ;

                TLogin data = result.getData();

                int uid = data.getUid() ;
                String username = data.getUsername() ;
                String token = data.getToken();
            }

        }

        @Override
        public void onError(Call call, Exception e, int id) {
            super.onError(call, e, id);
            ...
        }
    });

這樣無論data字段裏是什麼東西,都可以依葫蘆畫瓢創建POJO對象,然後去適配。

不過每次都用new TBaseCallback()來新建Callback也很煩,所以嘛,可以把它封裝到基類裏去,比如:

TBaseNetActivity.java

public abstract class TBaseNetActivity<T> extends TBaseActivity {

public void setContentView(...) {
    ...
    initCallBack();
}

private void initCallBack() {
    if (callback == null) {
        callback = new TBaseCallback<T>() {
            @Override
            public void onResponse(TOkHttpResponse<T> response, int id) {
                hideLoadingView();
                status = response.getStatus();
                if (status == 200) {
                    onSuccessResponse(response);
                } else {
                    ...
                    onFailResponse(error);
                }
            }

            @Override
            public void onError(Call call, Exception e, int id) {
                super.onError(call, e, id);
                ...
                hideLoadingView();
                onFailResponse(error);
            }
        };
    }
}

public TBaseCallback<T> getCallback() {
    if (callback == null) {
        initCallBack();
    }
    return callback ;
}

public void postRequest(String headM,Map<String,Object> pri_args) {
    showLoadingView();
    TBaseApi.createPostRequest(headM,pri_args,getCallback());
}

public abstract void onSuccessResponse(TOkHttpResponse<T> response);

public abstract void onFailResponse(TOkHttpError error);
}

這裏的思路就很簡單了,區分請求成功(返回碼200)和請求失敗的,只允許成功的進入onSuccessResponse方法裏,把錯誤邏輯都扔到onFailResponse裏,避免了原來在onResponse裏解析時的過多的判斷。TOkHttpError跟TOkHttpResponse類似,是封裝的錯誤返回碼

使用時創建Activity,傳入bean類,重寫父類的方法:

public class TMyActivity extends TBaseNetActivity<TBaseDataResult<TBean>> {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_main);
    //發送請求,因爲Okhttp-utils已經封裝成異步請求了,所以主線程中請求網絡是完全沒問題的
    postRequest(headM,pri_args);
}

@Override
public void onSuccessResponse(TOkHttpResponse<TBaseDataResult<TBean>> response) {
    //解析數據咯
}
@Override
public void onFailResponse(TOkHttpError error) {
    //失敗時的異常處理
}

}

關於網絡框架的封裝,差不多就涉及這些了。

github地址:https://github.com/herdotage/Android_sample/tree/master/LOkhttpUtils

發佈了51 篇原創文章 · 獲贊 26 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章