美文网首页Android
Handler中sendMessage和post方法的区别

Handler中sendMessage和post方法的区别

作者: Merbng | 来源:发表于2021-05-26 18:16 被阅读0次

    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一类的方法发送是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

    相关文章

      网友评论

        本文标题:Handler中sendMessage和post方法的区别

        本文链接:https://www.haomeiwen.com/subject/wdzksltx.html