当前位置: 移动技术网 > 移动技术>移动开发>Android > 详解Android的OkHttp包编写异步HTTP请求调用的方法

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

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;

@override
public 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);
}

@override
public void onviewcreated(view view, @nullable bundle savedinstancestate) {

  /* start */
  backgroundhandler.sendemptymessage(msg_query_data);
}

@override
public void ondestroyview() {

  /* 將message清空,backgroundthread結束掉 */
  backgroundhandler.removecallbacksandmessages(null);
  uihandler.removecallbacksandmessages(null);
  backgroundhandler.getlooper().quit();
  super.ondestroyview();
}

@override
public 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;
  }
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网