引言:
研究某个项目的时候发现,我看不懂它的线程通信部分,原来是Handler部分自己没有学好,所以来补一下。当你发送网络请求的时候,都是进行异步操作,因此不能直接进行UI方面的操作,这个时候你就可以通过handler向主线程发送消息,通知它更新UI。
正文:
1.Handler可以写成内部类,也可以写成外部类,我个人喜欢写成外部类,这样就能实现对handleMessage方法的重写,来进行UI的更新:
package com.example.test2.entities;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Html;
import android.util.Log;
import android.widget.TextView;
import androidx.fragment.app.FragmentActivity;
import com.example.test2.fragments.Fragment3;
public class MyHandler extends Handler {
private TextView mTextView;
private String mText;
private String mFailString;
public void onBindingMyData(TextView textView, String failstring){
mTextView=textView;
mFailString= Html.fromHtml(failstring).toString();
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case Fragment3.REQUEST_SUCCESS:
mText=msg.obj.toString();
mTextView.setText(mText);
break;
case Fragment3.REQUEST_FAIL:
mText=null;
mTextView.setText(mFailString);
break;
default:
break;
}
}
}
对于Handler的理解,可以看作是一种监听,每一次发送一条消息,就会触发一次事件处理,即调用handleMessage跟点击事件什么的其实差不多(个人观点,只是一个比喻),可以把我这一步抽象为设置点击监听。
2.实现消息发送:
首先,展示网络请求部分:
对OKhttp的同步与异步Get请求不清楚的,可以参考我另一篇博文:
OKhttp异步与同步GET请求
private void sendAsyncRequest(){
//发送异步get请求,本身就不在主线程运行
Log.w(TAG,""+Thread.currentThread());
OkHttpClient client = new OkHttpClient(); //创建一个窗口对象
Request request = new Request.Builder() //创建一个请求
.url("https://www.baidu.com")
.get() //表明为get请求
.build();
Call call=client.newCall(request); //创建一个Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
showRequestFail(textView);
Log.w(TAG+" fail",""+Thread.currentThread());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String responseData=response.body().string();
showRequestSuccess(textView,responseData);
Log.w(TAG+" success",""+Thread.currentThread());
}
});
}
然后,我们来重点关注回调的方法showRequestFail和showRequestSuccess。两个方法都包含Handler发送消息,我们以showRequestSuccess为例:
myHandler=new MyHandler();
myHandler.onBindingMyData(textView,mFailString);
private void showRequestSuccess(TextView textView, final String response){
Message message=Message.obtain();
message.obj=response;
message.what=REQUEST_SUCCESS;
Log.w("fragment3",message.what+" ^_^");
myHandler.sendMessage(message);
}
3.小结:先创建一个Handler对象,然后通过Message.obtain()获取message,message.what一般与handleMessage方法对应,通过message.obj还可以传递一个对象。
4.更多详细用法(大佬的博客):
Handler用法及解析