Android的消息机制

Posted 甜树果子二号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android的消息机制相关的知识,希望对你有一定的参考价值。

android的消息机制

Handler是Android中消息机制的上层接口,是的开发过程中只需要和Handler交互即可。通过Handler就可以将一个任务切换到Handler所在线程中执行。其中的一个应用场景就是在子线程中执行耗时操作例如读取文件访问网络等以后可以通过handler将更新UI(UI非线程安全,android当中不允许在子线程中更新;而耗时操作如果在主线程进行会造成ANR)的操作切换回主线程中执行。所以Android中的消息机制主要是指Handler的运行机制。

Handler创建时会采用当前线程的Looper来构建内部消息循环系统,然后可以通过Handler的post方法(内部也是通过send方法完成的)将一个Runnable对象投递到Handler内部的Looper中去处理,或者通过Handler的send方法发送一个消息到Looper中去处理,它会调用MessageQueue的enqueueMessage方法将这个消息放入消息队列待Looper处理。

ThreadLocal的作用

定义:是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后只能在指定的线程中获取到存储的数据。

使用场景:(1)当某些数据是以线程为作用域并且不同线程具有不同的数据副本时就可以采用ThreadLocal。(2)复杂逻辑下的对象传递,比如监听器的传递,有的时候一个线程中的任务过于复杂,可能表现为函数调用栈比较深以及代码入口的多样性,我们又需要监听器能够贯穿整个线程的执行过程,这个时候可以采用ThreadLocal。

不同的线程访问同一个ThreadLocal的get方法,ThreadLocal内部会从各自的线程中取出一个数组,然后再从数组中根据当前ThreadLocal的索引去查找对应的value值,不同线程中的数组是不同的,所以可以通过ThreadLocal在不同线程中维护一套数据的副本而互不干扰。

消息队列的工作原理

MessageQueue通过单链表数据结构来维护消息列表;

boolean enqueueMessage(Message msg, long when) 插入消息,也就是单链表的插入;

Message next() 取出一条消息并从消息队列中删除,next是一个无限循环的方法,如果消息队列中没有消息就会阻塞在这里,而有消息到来就会返回这条消息并从单链表中删除。

Looper的工作原理

消息循环:会不停地从MessageQueue中查看是否有新消息,如果有新消息就会立刻处理,否则会阻塞。

private Looper(boolean quitAllowed) 构造方法中创建消息队列MessageQueue,并保存当前线程对象;
public static void prepare() 为当前线程创建Looper,保证Handler可以工作;
public static void loop() 调用了这个方法,消息系统才会真正起作用。loop是个死循环,只有当messageQueue.next()返回null才退出循环,也就是消息队列退出时。

Handler的工作原理

handler发送消息的典型过程如下,可以看出这就是想消息队列中插入了一条消息,然后MessageQueue的next方法会返回这条消息给Looper处理,最终交给Handler处理,也就是Handler的dispatchMessage方法会被调用,Handler就进入了处理消息的阶段。

public final boolean sendMessage(Message msg)
public final boolean sendMessageDelayed(Message msg, long delayMillis)
public boolean sendMessageAtTime(Message msg, long uptimeMillis) 
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis)
public void dispatchMessage(Message msg)
public void handleMessage(Message msg)//子类重写或者是Callback内部的handleMessage方法

另外关于构造方法

public Handler() 
public Handler(Callback callback, boolean async) //在这个方法内会去判断当前线程有无Looper,如果没有的话就会抛出异常。

主线程的消息循环

Android的主线程就是ActivityThread,主线程的入口方法为main,在main方法中系统会通过Looper.prepareMainLooper()来创建主线程的Looper以及MessageQueue,并通过Looper.loop()来开启主线程的消息循环。主线程消息循环开始以后,ActivityThread还需要一个Handler来和消息队列进行交互,这个Handler就是ActivityThread.H,它内部定义了一组消息类型,主要包含了四大组件的启动和停止等过程。ActivityThread通过ApplicationThread和AMS进行进程间通信,AMS以进程间通信的方式完成ActivityThread的请求后会回调ApplicationThread的Binder方法,然后ApplicationThread会向H发送消息,H收到消息后会将ApplicationThread中的逻辑切换到ActivityThread中去执行,即切换到主线程中执行,这个过程就是主线程消息循环模型。

以上是关于Android的消息机制的主要内容,如果未能解决你的问题,请参考以下文章

Android中的消息机制

Android HandlerThread 消息循环机制之源代码解析

从Handler+Message+Looper源代码带你分析Android系统的消息处理机制

[Android源代码分析]Android消息机制,Handler,Message,Looper,MessageQueue

Android Framework 分析---2消息机制Native层

Win32窗口消息机制 x Android消息机制 x 异步执行