首页 > 系统 > Android > 正文

详解Android的OkHttp包编写异步HTTP请求调用的方法

2019-12-12 06:01:07
字体:
来源:转载
供稿:网友

OkHttp 除了支持常用的同步 HTTP 请求之外,还支持异步 HTTP 请求调用。在使用同步调用时,当前线程会被阻塞,直到 HTTP 请求完成。当同时发出多个 HTTP 请求时,同步调用的性能会比较差。这个时候通过异步调用可以提高整体的性能。
在通过 newCall 方法创建一个新的 Call 对象之后,不是通过 execute 方法来同步执行,而是通过 enqueue 方法来添加到执行队列中。在调用 enqueue 方法时需要提供一个 Callback 接口的实现。在 Callback 接口实现中,通过 onResponse 和 onFailure 方法来处理响应和进行错误处理。
异步调用的示例

public class AsyncGet {  public static void main(String[] args) throws IOException {  OkHttpClient client = new OkHttpClient();  Request request = new Request.Builder()      .url("http://www.baidu.com")      .build();  client.newCall(request).enqueue(new Callback() {    public void onFailure(Request request, IOException e) {      e.printStackTrace();    }    public void onResponse(Response response) throws IOException {      if (!response.isSuccessful()) {        throw new IOException("服务器端错误: " + response);      }      System.out.println(response.body().string());    }});  }}

觉得okHttp最难写的地方应该就是Callback了。
相信很多人都会遇到,如果Callback回来之后,我的Activity finish了,或是我的Fragment replace了。
此时更改UI,就会产生找不到View的问题。
而且Callback回来,居然是在backgroundThread上,
这时候如果要操作View又要切换到mainThread去,略显麻烦。
所以我在写的时候,是没有使用Callback的 以下提供一种漂亮(自认...)的写法给大家做参考。

/* 以fragment为例 */public class BaseFragment extends Fragment implements Handler.Callback {private static final int MSG_QUERY_DATA = 0x00;private static final int MSG_DISPLAY_DATA = 0x01;@Overridepublic void onAttach(Activity activity) {  super.onAttach(activity);  this.activity = activity;  /* setup handler */  HandlerThread handlerThread = new HandlerThread(getClass().getName());  handlerThread.start();  backgroundHandler = new Handler(handlerThread.getLooper(), this);  uiHandler = new Handler(activity.getMainLooper(), this);}@Overridepublic void onViewCreated(View view, @Nullable Bundle savedInstanceState) {  /* start */  backgroundHandler.sendEmptyMessage(MSG_QUERY_DATA);}@Overridepublic void onDestroyView() {  /* Message清空,backgroundThread束掉 */  backgroundHandler.removeCallbacksAndMessages(null);  uiHandler.removeCallbacksAndMessages(null);  backgroundHandler.getLooper().quit();  super.onDestroyView();}@Overridepublic boolean handleMessage(Message msg) {  /* 如果fragment不在Activity上了,直接return掉,避免NPE */  if (!isAdded()) return false;  /* 做各MSG */  switch(msg.what){    case MSG_QUERY_DATA:      // do okHttp without callback      Response response = client.newCall(request).execute();      // 回 uiThread 做UI更新      Message respMsg = uiHandler.obtainMessage();      respMsg.what = MSG_DISPLAY_DATA;      respMsg.obj = response;      backgroundHandler.sendMessage(respMsg);      break;    case MSG_DISPLAY_DATA:      Response apiResponse = (Response)msg.obj;      // 失      if(null == apiResponse){        //show error      }      // 成功      else{        //display data on UI      }      break;    return false;  }}

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表