android 消息机制

来源:互联网 发布:网络福建师范大学校长 编辑:程序博客网 时间:2024/06/06 07:37

android消息机制大家并不陌生,我这篇博客会从源码的角度来解析android的消息机制。

      首先,android的消息机制就是指Handler的运行机制,Handler的运行需要底层MessageQueue和Looper的支持。MessageQueue就是一个消息队列,虽然叫消息队列,但是它的内部存储结构并不是消息队列,而是采用单链表的数据结构才存储消息列表。Looper是一个消息循环,由于MessageQueue只是一个消息存储的单元,它不能处理消息,而Looper就填补了这个功能。Looper会以无限循环的方式去查找是否有新消息,如果有的话就处理消息,否则就一直等待。Looper有一个特殊的概念,那就是ThreadLocal,ThreadLocal并不是线程,它的作用是可以在每个线程中存储数据。我们可以通过ThreadLocal拿到Looper。ThreadLocal可以在不同的线程中互不干扰的存储并提供数据。需要注意的是,线程默认没有Looper的,如果要使用Handler,就必须为线程创建Looper。有人问,我在Activity里面创建Handler并没有创建Looper。这是因为主线程被创建时就初始化Looper了,所以,不用自己手动创建。主线程就是UI线程,它就是ActivityThread, ActivityThread被创建时就会初始化looper,这也是在主线程中默认可以使用handler的原因。

     android的消息机制主要是指handler的运行机制以及handler所附带的MessageQueue和Looper的工作过程。这三者实际上是一个整体。只不过我们在开发过程中接触更多的是handler。handler的主要作用是将一个任务切换到某个指定的线程中去执行。更新UI只是一部分功能,并非全部。

     为什么不允许在子线程中访问UI呢?如果在多线程中并发访问UI可能会导致UI控件出现不可预期的状态,那为什么系统不对UI控件访问加锁呢?缺点有2个,首先,加上锁机制会让UI访问逻辑变得复杂;其次,锁机制会降低UI访问的效率,因为锁机制会阻塞某些线程的执行。鉴于这2个缺点,最简单高效的办法就是采用单线程模型来处理UI操作。

     MessageQueue是消息队列,但是它的实现并不是队列,而是采用单链表的数据结构,因为它在插入和删除上比较有优势。

     Looper除了prepare方法外,还提供了prepareMainLooper方法,这个方法主要给主线程也就是ActivityThread提供创建Looper使用的,其本质也是通过prepare方法实现的。由于主线程的Looper比较特殊,所以Looper提供了一个getMainLooper的方法,通过它可以在任何地方获取到主线程的Looper.

     Handler的工作原理。handle发生消息的过程仅仅是向消息队列中插入了一条消息。MessageQueue的next方法会返回给Looper,Looper收到消息后就开始处理。最终消息由Looper交由handler处理,即handler的dispatchMessage方法会被调用,这时Handler就进入了处理消息的阶段。handler处理消息的过程如下:首先,检查message的callback是否为null,不为null就通过handleCallback方法来处理消息。message的callback是一个Runnable对象,实际上就是Handler的post方法所传递的Runnable参数。其次,检查mCallback是否为null,不为null就调用mCallback的handleMessage方法来处理消息。Callback是一个接口。通过Callback可以采用如下方式来创建handler对象:

 Handler handler = new Handler(callback);
那么Callback的意义是什么呢?源码注释已经做了说明,在日常开发中常见的方式就是创建一个handler的子类来处理消息,Callback 的另一种方式就是实现这个接口。
    handler还由一个特殊的构造方法,就是指定一个Looper。

0 0