對OkHttpUtils中onError方法進行擴充套件列印更多資訊
https://www.2cto.com/kf/201707/661662.html
最近開發Android專案用到了OkHttpUtils,專案中的伺服器是另一個同學搭的,能測試伺服器的介面的只有我了,比如400,500錯誤啊,都要我這邊列印才能找到出錯具體在哪個程式碼塊,但是,OkHttpUtils的錯誤資訊居然只有打印出響應碼,這真是讓人很無語啊。然後就花時間研究起背後的故事。
先附上OkHttpUtils的作者和用法:Android 一個改善的okHttp封裝庫
首先看一下普通返回的String型別的StringCallback
OkHttpUtils.get() .url(url) .build() .execute(new StringCallback() { @Override public void onError(Call call, Exception e, int id) { e.printStackTrace(); Log.i(TAG, e.getMessage()); } @Override public void onResponse(String response, int id) { Log.i(TAG, response); } });
我們看到onError方法用了兩種方式列印,但是結果確是
藍色部分是e.printStackTrace();
黑色部分是Log.i(TAG, e.getMessage());
我們發現確實只能列印響應碼。。。
那要如何輸出錯誤的網頁全部資訊呢,我們來看看基類Callback
public abstract class Callback<t> { /** * UI Thread * * @param request */ public void onBefore(Request request, int id) { } /** * UI Thread * * @param */ public void onAfter(int id) { } /** * UI Thread * * @param progress */ public void inProgress(float progress, long total , int id) { } /** * if you parse reponse code in parseNetworkResponse, you should make this method return true. * * @param response * @return */ public boolean validateReponse(Response response, int id) { return response.isSuccessful(); } /** * Thread Pool Thread * * @param response */ public abstract T parseNetworkResponse(Response response, int id) throws Exception; public abstract void onError(Call call, Exception e, int id); public abstract void onResponse(T response, int id); public static Callback CALLBACK_DEFAULT = new Callback() { @Override public Object parseNetworkResponse(Response response, int id) throws Exception { return null; } @Override public void onError(Call call, Exception e, int id) { } @Override public void onResponse(Object response, int id) { } }; }
裡面有一個方法validateReponse(Response response, int id),上面的註釋if you parse reponse code in parseNetworkResponse, you should make this method return true.大概意思就是要解析資料就返回true吧,那我們就重寫這個方法,都返回true看會發生什麼
好像列印了錯誤的網頁,但是仔細一看發現是onResponse中列印的,那表明onError方法就沒用了,導致所有事情都要在onResponse中處理了(雖然本來就是都在這裡處理的)。那有沒有方法讓錯誤的響應碼提交到onError中呢?我們再看Callback類的validateReponse方法,它返回的是response.isSuccessful();,我們繼續探索進去,發現如下程式碼
public boolean isSuccessful() {
return code >= 200 && code < 300;
}
也就是說只有響應碼是200到300間的才會走onResponse方法(沒改之前),那都返回true要在哪裡處理呢。看回validateReponse的註釋,裡面出現了parseNetworkResponse這個方法,這個方法有引數Response,這個可以得到響應碼,然後還丟擲一個Exception,而onError方法中剛好有一個Exception的引數,於是有一個大膽的猜想,parseNetworkResponse丟擲的異常在onError中接收,所以重寫這個方法
@Override
public String parseNetworkResponse(Response response, int id) throws Exception {
if(response.code()>=200 && response.code()<300){
return response.body().string();
}else{
throw new Exception("code is:"+response.code()+"\n"+response.body().string());
}
}
當響應碼為200到300時,我們返回響應體,其餘情況我們丟擲一個異常到onError中,結果如我們所想
至此就完成了對OkHttpUtils中StringCallback中onError的擴充套件,附上自己重寫的MyStringCallback類
public abstract class MyStringCallback extends Callback<string> {
@Override
public boolean validateReponse(Response response, int id) {
return true;
}
@Override
public String parseNetworkResponse(Response response, int id) throws Exception {
if(response.code()>=200 && response.code()<300){
return response.body().string();
}else{
throw new Exception("code is:"+response.code()+"\n"+response.body().string());
}
}
}