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

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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值