Android Handler消息机制
2018-05-06 本文已影响28人
十思叶
简单应用场景
- 在子线程向主线程发送消息,一般刷新主线程的UI
- 主线程向子线程发送消息, 一般为启动异步阻塞任务
class MessageMechanismActivity : AppCompatActivity() {
companion object {
private const val TAG = "MessageMechanism"
private const val MSG_UPDATE_START = 1
private const val MSG_UPDATE_OVER = 2
}
private var mainHandler: Handler? = null
private var threadHandler: Handler? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_message_mechanism)
// thread1 -> main thread
mainHandler = TestHandler() // main thread中
this.btn_handler_in_main.setOnClickListener{
mainHandler!!.sendEmptyMessage(MSG_UPDATE_START)
// thread1
object : Thread() {
override fun run() {
Thread.sleep(2000)
// thread1->threadMain
mainHandler!!.sendEmptyMessage(MSG_UPDATE_OVER)
}
}.start()
}
// main thread -> thread2
// thread2
object : Thread() {
override fun run() {
Looper.prepare()
threadHandler = TestHandler() // 在此线程中创建Handler
Looper.loop()// may block
}
}.start()
this.btn_handler_in_other_thread.setOnClickListener {
// threadMain -> thread2
threadHandler!!.sendEmptyMessage(MSG_UPDATE_START)
}
}
class TestHandler : Handler() {
init {
Log.d(TAG, "init:${Thread.currentThread().name}")
}
override fun handleMessage(msg: Message?) {
Log.d(TAG, "thread:${Thread.currentThread().name}")
super.handleMessage(msg)
when(msg?.what){
MSG_UPDATE_START -> {
val sdf = SimpleDateFormat("HH:mm:ss", Locale.CHINA)
Log.d(TAG, "开始更新:${sdf.format(Date())}")
}
MSG_UPDATE_OVER -> {
val sdf = SimpleDateFormat("HH:mm:ss", Locale.CHINA)
Log.d(TAG, "完成更新:${sdf.format(Date())}")
}
}
}
}
}
类说明
Thread
- 成员 ThreadLocal.ThreadLocalMap。用于存储各种ThreadLocal数据
ThreadLocal
- 一个对象能在多个线程中保存各自的数据,保存或获取数据时会调用当前线程的ThreadLocal.ThreadLocalMap进行处理
Looper
- 成员MessageQueue
- 成员Thread。创建Looper的当前线程
- 成员ThreadLocal< Looper >, 用于在当前线程存储当前Looper
MessageQueue
Handler
- 成员Looper。当前线程的Looper
- 成员MessageQueue。Looper中的MessageQueue
Handler发送消息流程
- 在线程A中,创建Looper、MessageQueue、Handler,并用Looper维护MessageQueue
- 在线程B中,调用Handler发送消息,添加消息到MessageQueue;
- 在线程A中,Looper从MessageQueue拿出消息交给Handler处理

线程A中,创建Looper和MessageQueue
->Looper.prepare()。创建Looper和MessageQueue,并在当前线程的ThreadLocalMap中保存Looper
private static void prepare(boolean quitAllowed) {
// 一个线程只能创建一个Looper
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
// 创建Looper并保存在当前线程的ThreadLocalMap中
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
线程A中,创建Handler
->Handler()
// Handler.class
public public Handler(Callback callback, boolean async) {
// ...
// 获取当前线程的Looper
mLooper = Looper.myLooper();
// 当前线程中没有Looper则不能创建
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
// ...
}
// Looper.class
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
// ThreadLocal.class
// 从当前线程中的ThreadLocalMap中获取ThreadLocal值
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
线程A中,Looper维护MessageQueue
-> Looper.loop()
// Looper.loop核心代码
public static void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
for (;;) {
// might block.因为queue.next()也是一个永真循环
Message msg = queue.next();
// msg.target是Handler,一般最终会调用Handler.handleMessage
msg.target.dispatchMessage(msg);
}
}
//MessageQueue.class 轮询取出消息
Message next() {
for (;;) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
}
}
B线程中,发送消息
->Handler.sendMessage()->...->Handler.enqueueMessage()// 会设置msg.target = this
->MessageQueue.enqueueMessage()// 添加消息到消息队列
// MessageQueue.class 添加消息到消息队列相关代码
boolean enqueueMessage(Message msg, long when{
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// 插到头部
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// 插入到队列中间
Message prev;
for (;;) {
p = p.next;
if (p == null || when < p.when) {
// 插入规则:或者是最后一个,或者根据处理事件顺利插入
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
}
A线程中,拿出消息并处理
->Looper.loop()->Handler.dispatchMessage()
->message.callback.run() || mCallback.handleMessage(msg) || handleMessage(msg);
// Handler.class
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}