Handler中sendMessage和post方法的区别
2021-05-26 本文已影响0人
Merbng
sendMessage 的用法
public class MainActivity extends AppCompatActivity{
private TextView mTextView;
private String new_str="";
//实例化Handler ,重写回调方法
Handler mHandler =new Handler(){
public void handleMessage(Message msg){
if(msg.what ==0){
//sendMessage 方法更新UI的操作必须在handler的handleMessage回调中完成
mTextView.setText(new_str);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable(){
@Override
public void run(){
new_str ="sendMessage更新UI";
//sendMessage方法解决UI更新发送消息给handler(主线程中的handler)
mHandler.sendEmptyMessage(0);
}
}).start();
}
}
post的用法
public class MainActivity extends AppCompatActivity{
private TextView mTextView;
private String new_str="";
//实例化Handler
private Handler mHandler =new Handler();
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这里调用了post方法,和sendMessage一样达到了更新UI的目的
mHandler.post(new Runnable(){
@Override
public void run(){
mTextView.setText(new_str);
}
}).start();
}
}
上面两种方法都是常见的(这里未考虑内存泄露,重点只关注Handler的使用),使用这两种方法都能实现UI的更新。
源码分析
handler中的post源码
public final boolean post(Runable r){
return sendMessageDelayed(getPostMessage(r),0);
}
//获得了message实例,将r赋给callback,接下来还是和sendMessage一致的操作,进入sendMessageDelayed
private static Message getPostMessage(Runnable r){
Message m= Message.obtain();
m.callback=r;
return m;
}
public final boolean sendMessageDelayed(Message msg,long delayMillis){
if(delayMillis <0){
delayMillis =0;
}
return sendMessageAtTime(msg,SystemClock.uptimeMillis()+delayMillis);
}
最终还是到sendMessageAtTime
这个方法里面
public boolean sendMessageAtTime(Message msg,long uptimeMillis){
MessageQueue queue =mQueue;
if(queue == null){
RuntimeException e =new RuntimeException(this+ " sendMessageAtTime() called with no mQueue");
Log.w("Looper",e.getMessage(),e);
return false;
}
return enqueueMessage(queue,msg,uptimeMillis);
}
所以可以知道,handler.post
和handler.sendMessage
本质上是没有区别的,都是发送一个消息到消息队列中,只不过post使用方式更简单。
在handler的出队列方式中,可以看到如何进入不同的回调。
public void dispatchMessage(Message msg){
//如果是post,callback不为空,直接进入handleCallback
if(msg.callback != null){
handleCallback(msg);
}else{
//如果是sendMessage,且创建handler时没有传入callback,则callback为空,直接进入handleMessage,也就是我们自己复写的处理Message的方法
if(mCallback !=null){
if(mCallback.handleMessage(msg)){
return;
}
}
handleMessage(msg);
}
}
//直接run并不会启动新线程,所以这就是post的runnable里面可以直接更新UI的原因
private static void handleCallback(Message msg){
msg.callback.run();
}
post和sendMessage两类发送消息的方法有什么区别?
-
post一类的方法发送是Runnable对象,但是最后还是会被封装成Message对象,
将Runnable对象赋值给Message对象中的callback字段,然后交由sendMessageAtTime()方法 发送出去。
在处理消息时,会在dispatchMessage()方法里首先被handleCallback(msg)方法执行,实际上就是执行Message对象里面的Runnable对象的run方法。 -
sendMessage一类方法发送的消息直接是Message对象,处理消息时,在dispatchMessage里优先级会低于handleCallback(msg)方法,
是通过自己重写的handleMessage(msg)方法执行。
最终总结
post和sendMessage本质上是没有区别的,只是实际用法中有一点差别
post也没有独特的作用,post本质上还是用sendMessage实现的,post只是一种更方便的用法而已。
参考链接:
https://www.it610.com/article/1295510472333795328.htm