Android的消息机制

时间:2022-04-15 05:38:36

1、背景                                                               

Handler是Android消息机制的上层接口,通过handler可以轻松地将一个任务切换到Handler所在的线程中去执行。

Handler的作用之一是更新UI,有时候需要在子线程中进行耗时的I/O操作,可能是读取文件或者访问网络等,当耗时操作完成以后可能需要在UI上做一些改变,这时用Handler。

Android的消息机制主要是指Handler的运行机制,Handler的运行需要底层的MessageQueue(消息队列Looper(消息循环)的支撑。

消息队列采用单链表的数据结构来存储消息列表。

Looper以无限循环的形式去查找是否有新消息。Looper中有一个特殊的概念,ThreadLocal,它的作用是在每个线程中存储数据。

Handler创建的时候回采用当前线程的Looper来构造消息循环系统,那么Handler内部是通过ThreadLocal来获取到当前线程的Looper。线程默认没有Looper,如果需要使用Handler就必须为线程创建Looper。

我们经常提到的主线程,也叫UI线程,就是ActivityThread,ActivityThread被创建的时候就会初始化Looper,这也是在主线程中默认可以使用Handler的原因。

2、Android的消息机制概述                                   

Handler的主要作用是将一个任务切换到某个指定的线程中去执行。系统提供Handler的原因是为了解决在子线程中无法访问UI的矛盾。

Android规定访问UI只能在主线程中进行,如果在子线程中访问UI,那么程序就会抛出异常。

Android的UI空间不是线程安全的

ViewRootImpl对UI操作做了验证,这个验证工作是由ViewRootImpl的checkThread方法来完成的。

通过Handler的post方法将一个Runnable投递到Handler内部的Looper中去处理。其实post方法最终是通过send方法完成的。

当Handler的send方法被调用时,它会调用MessageQueue的enqueueMessage方法将这个消息放入消息队列中,然后Looper发现有新消息到来,就会处理这个消息,最终消息中的Runnable或者Handler的handleMessage方法就会被调用。

3、消息队列的工作原理                                          

消息队列在Android中指的是MessageQueue,主要包含两个操作:插入enqueueMessage和读取next。插入是往消息队列中插入一条消息,next的作用是从消息队列中取出一条消息并将其从消息队列中移除。

MessageQueue是通过一个单链表的数据结构来维护消息列表。

next是一个无限循环的方法,如果消息队列中没有消息,那么next方法会一直阻塞在这里。当有新消息到来时,next方法会返回这条消息并将其从单链表中移除。

4、Looper的工作原理                                           

Looper在Android的消息机制总扮演者消息循环的角色,它会不停地从MessageQueue中查看是否有新消息。

Handler的工作需要Looper,没有Looper的线程就会报错。通过Looper.prepare()可为当前线程创建一个Looper,接着通过Looper.loop()方法开启消息循环。

 

1 Looper.prepare();
2 Handler handler = new Handler();
3 Looper.loop();

 

5、Handler的工作原理                                         

Handler的工作主要包含消息的发送和接受过程。

消息的发送通过post的一系列方法和send的一系列方法来实现,post的一系列方法最终是通过send的一系列方法来实现的。

Handler发送消息的过程仅仅是向消息队列中插入了一条消息,MessageQueue的next方法就会返回这条消息给Looper,Looper收到消息就开始处理了,最终消息由Looper交给Handler的dispatchMessage方法处理。

Callback的意义是可以用来创建一个Handler的实例但并不需要派生Handler的子类。

最后,调用handler的handleMessage方法来处理消息。

6、主线程的消息循环                                              

Android的主线程就是ActivityThread,主线程的入口方法是main,在main方法中系统会通过Looper.prepareMainLooper()来创建主线程的Looper以及MessageQueue,并通过Looper.loop()来开启主线程的消息循环。

主线程的消息循环开始了以后,ActivityThread还需要一个Handler来和消息队列进行交互,这个Handler就是ActivityThread.H,它内部定义了一组消息类型,主要包含了四大组件的启动和停止等过程。

ActivityThread通过ApplicationThreadAMS进行进程间通信,AMS以进程间通信的方式完成ActivityThread的请求后会回调ApplicationThread中的Binder方法,然后ApplicationThread会向H发送消息,H收到消息后会将ApplicationThread中逻辑切换到ActivityThread中去执行,即切换到主线程中去执行,这个过程就是主线程的消息循环模型