Android程序员

Android Handler消息机制

2018-05-06  本文已影响28人  十思叶

简单应用场景

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

Looper

MessageQueue

Handler

Handler发送消息流程

image.png

线程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);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读