Handler(一)

APP 入口

ActivityThread.main()
public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        //其他代码省略...
        
        Looper.prepareMainLooper();//创建Looper及MessageQueue,且MessageQueue不允许销毁

        
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
Looper.prepareMainLooper()
 public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }
Looper.prepare(false)
 private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed)); //创建Looper及MessageQueue,quitAllowed=false表示MessageQueue不允许销毁,即主线程不允许销毁
    }
Looper.loop() 轮询消息,死循环
   public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        if (me.mInLoop) {
            Slog.w(TAG, "Loop again would have the queued messages be executed"
                    + " before this one completed.");
        }

        me.mInLoop = true;
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();
        for (;;) {//死循环,不断从消息队列取消息
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            /**
            **其他代码省略
            **/
    
            msg.target.dispatchMessage(msg);
            msg.recycleUnchecked();
        }
    }

消息处理流程

在子线程中调用Handler.sendMessage()–>Handler.enqueueMessage()–>MessageQueue.enqueueMessage()–>looper.loop()–>MessageQueue.next()–> msg.target.dispatchMessage(msg)–>Handler.dispatchMessage(msg)–>Handler.handleMessage(msg)

MessageQueue

由单链表实现的优先级队列(插入排序(时间),先进先出)

一个线程只有一个Looper

ThreadLocalMap–>ThreadLocal

线程阻塞

  • message 不到时间:到时间时自动唤醒
  • MessageQueue 为空:无限等待,等sendMessage后,在enqueueMessage中nativeWake唤醒

MessageQueue.quit()

子线程消息队列为空 quit()–>MessageQueue.next()=null–>loop退出
主线程不允许quit()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值