Handler中sendMessage和post方法的区别

文章目录

  • sendMessage 的用法
  • post的用法
  • 源码分析
    • handler中的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.posthandler.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();
}

最终总结:

  1. post和sendMessage本质上是没有区别的,只是实际用法中有一点差别
  2. post也没有独特的作用,post本质上还是用sendMessage实现的,post只是一中更方便的用法而已

你可能感兴趣的:(Android,Java)