android消息机制1-整体概览

应用程序入口:

ActivityThread类中

public static void main(String[] args) {
  
  

    Looper.prepareMainLooper();

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

    // End of event ActivityThreadMain.
 
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

可以知道,程序初始化就会在主线程预加载MainLooper

public static void prepareMainLooper() {
    prepare(false);
    ...
        sMainLooper = myLooper();
    }
}


private static void prepare(boolean quitAllowed) {
    sThreadLocal.set(new Looper(quitAllowed));
}

public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}


以上就是Looper.prepareMainLooper()的过程,可以看出先在ThreLocal准备Looper对象,然后get Looper对象,先设置后获取再使用,不会为null

额外提一下ThreadLocal是个什么类?

* Implements a thread-local storage, that is, a variable for which each thread
* has its own value. All threads share the same {@code ThreadLocal} object,
* but each sees a different value when accessing it, and changes made by one
* thread do not affect the other threads.
就是说作用范围线程域,同一进程中的所有线程共享这个对象,但是每个线程根据其映射的值又不同

举个栗子,月亮只有一个,每个人中秋晚上赏月看到的月亮都不同

然后Looper进行loop()

public static void loop() {
    final Looper me = myLooper();
   
    final MessageQueue queue = me.mQueue;

    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();
    }
}

看loop的过程,先得到消息队列queue=me.mQueue,这个队列是什么时候初始化的呢

private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}
是在给ThreadLocal绑定Looper时候初始化的。

既然消息队列有了,那就一个一个开始取吧,永真循环就开始了

当取到了消息之后,Handler就会分发消息dispatchMessage(msg)

岔开说一下,msg.target就是发送该消息的Handler对象

每一个轮询出来的消息都会持有一个发送该消息的引用,因为入队列时就保证了target不为null

源码在Handler中如下

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}

回归主线,Hander分发消息

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}

如果没有msg的Runnable任务或者Handler的回调,那么就会调用handleMessage(msg),这个方法就是调用者实现。

至此消息机制的整体流程讲完了。

有几个问题还要讲下:

1,既然是Looper一直在死循环,为何不引起阻塞,对性能有何影响

答案是linux的管道通信机制






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值