網路請求工具類之OkHttp3封裝(二)下(支援請求取消、非同步請求的執行緒切換)
阿新 • • 發佈:2019-02-11
緊接著上篇說的任務2:非同步請求採用UI執行緒回撥方式。
首先採用Handler進行執行緒間的通訊,順便優化下回調方法,加入HttpInfo以做到工具類使用的滲透性。
在OkHttpUtil中宣告一個自定義的非同步回撥介面,該介面對網路請求介面進行了封裝,使同步、非同步請求處理流程保持一致性,程式碼如下:
/** * 非同步請求回撥介面 */ public interface CallbackOk { /** * 該回調方法已切換到UI執行緒 */ void onResponse(HttpInfo info) throws IOException; }
在OkHttpUtil中增加Handler業務排程程式碼:
private final static int WHAT_CALLBACK = 1;
/** * 主執行緒業務排程 */ private static Handler handler = new Handler(Looper.getMainLooper()){ @Override public void handleMessage(Message msg) { final int what = msg.what; switch (what){ case WHAT_CALLBACK: try { CallbackMessage callMsg = (CallbackMessage) msg.obj; callMsg.callback.onResponse(callMsg.info); }catch (Exception e){ e.printStackTrace(); } break; } } };
修改OkHttpUtil中非同步請求方法:
/** * 非同步請求 * @param info * @param method * @param callback */ private void doRequestAsync(HttpInfo info, Method method, CallbackOk callback){ if(null == callback) throw new NullPointerException("CallbackOk is null that not allowed"); Call call = httpClient.newCall(fetchRequest(info,method)); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { showLog(e.getMessage()); } @Override public void onResponse(Call call, Response res) throws IOException { //主執行緒回撥 handler.sendMessage(new CallbackMessage(WHAT_CALLBACK,callback,dealResponse(info,res)).build()); } }); putCall(info,call); }
這樣邏輯應該很清晰了,非同步請求後通知Handler進行回撥,Handler負責執行緒的通訊(即回撥),這裡CallbackMessage是對Messay進行了包裹,增加了CallbackOk與HttpInfo屬性。
/**
* 回撥資訊實體類
*/
public class CallbackMessage{
public int what;
public CallbackOk callback;
public HttpInfo info;
public CallbackMessage(int what, CallbackOk callback, HttpInfo info) {
this.what = what;
this.callback = callback;
this.info = info;
}
public Message build(){
Message msg = new Message();
msg.what = this.what;
msg.obj = this;
return msg;
}
}
這裡對網路請求方法進行了自定義的封裝處理:private HttpInfo dealResponse(HttpInfo info, Response res){
try {
if(null != res && null != res.body()){
if(res.isSuccessful()){
return retInfo(info,info.SUCCESS,res.body().string());
}else{
showLog("HttpStatus: "+res.code());
if(res.code() == 404)//請求頁面路徑錯誤
return retInfo(info,info.CheckURL);
if(res.code() == 500)//伺服器內部錯誤
return retInfo(info,info.NoResult);
if(res.code() == 502)//錯誤閘道器
return retInfo(info,info.CheckNet);
if(res.code() == 504)//閘道器超時
return retInfo(info,info.CheckNet);
}
}
return retInfo(info,info.CheckURL);
} catch (Exception e) {
return retInfo(info,info.NoResult);
}
}
下面我們來看下Activity/Fragment的非同步網路請求程式碼:
private void doHttpAsync() {
OkHttpUtil.Builder().build().doGetAsync(HttpInfo.Builder().setUrl(url).build(this), info -> {
if (info.isSuccessful()) {
String ret = info.getRetDetail();
tv_content.setText(ret);
}
});
}
可以看出onResponse回撥方法已經是在UI執行緒了,可以盡情修改介面,再也不用runOnUIThread包裹,這裡採用了Lambda表示式,程式碼看起來是不是清爽多了。
專案已上傳至GitHub:https://github.com/MrZhousf/OkHttp3