Android

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.posthandler.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和sendMessage本质上是没有区别的,只是实际用法中有一点差别
post也没有独特的作用,post本质上还是用sendMessage实现的,post只是一种更方便的用法而已。
参考链接:
https://www.it610.com/article/1295510472333795328.htm

上一篇下一篇

猜你喜欢

热点阅读