美文网首页
Handler的sendMessage和post的区别

Handler的sendMessage和post的区别

作者: john_luo | 来源:发表于2016-09-07 21:22 被阅读1253次

    我们常常使用Handler来更新UI,但是很多同学对Handler的sendMessage和post的区别不是很了解,我们先看使用方式的区别:

    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的更新,那么post和sendMessage有什么区别呢,我们要跟踪源码来看看post到底做了什么。

    handler中post的源码:

    public final boolean post(Runnable 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的出队列方式中,可以看到如何进入不同的回调

    消息出队列源码

     /**
     * Handle system messages here.
     */
       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 message) {
        message.callback.run();
    }

    相关文章

      网友评论

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

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