天天看点

android handler的机制和原理_Handler机制原理

说到 Android 消息机制,就不得不谈到 Handler 机制,接下来本文以 android-29 的源码分析 Handler 机制的原理。

首先 Handler 是在 android.os 包下,与它在同一个包下的 Looper,Message,MessageQueue 等就是本文的重点。

// 举个例子
           

这是 handler 在子线程使用的典型实例,下面按步骤分析:

1. Looper.prepare()

static 
           

调用后创建了 MessageQueue 和 Looper,并把 looper 的实例放入 ThreadLocal 中保存

2. 创建 handler

Handler提供了两种使用方式

第一种方式是直接实例化,调用handler的构造函数

//Handler.java#构造函数一
           

构造函数里有三个参数,分别是

looper:创建了 MessageQueue,在某个线程中遍历对应的消息队列,相当于发动机的角色。

callback:定义了 handleMessage() 方法,对接收到的消息进行处理,相当于快递分拣员的角色。

async:设置消息是否异步,默认是同步的,如果是异步将不受同步障碍的约束。

第二种方式是继承 handler,重写 handleMessage() 方法。

创建 handler 后,handler 就持有了 looper 和 messageQueue 的对象引用, 通过调用 sendMessage() 方法往 messageQueue 中发送消息,其实最终调用的是 MessageQueue的enqueueMessage() 方法

boolean 
           

TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t))); 这行代码会不断地调用write()方法,直到管道中的数据全部读完

3.Looper.loop()

//Looper.java#裁剪代码
           

这里重点分析 Message msg = queue.next();

Message 
           

mPtr的赋值是nativeInit(),网上暂时没找到Android Q的在线查看,暂时以Android P来分析native层的逻辑。 native层创建NativeMessageQueue对象后将对象id返回给java层,其中NativeMessageQueue创建时创建了Looper对象, 与java层Looper对象在创建时创建了MessageQueue对象恰恰相反

static 
           

nativePollOnce()调用到native层,将mPtr根据id转为NativeMessageQueue对象

static 
           

至此流程分析结束,下面附上总结图

android handler的机制和原理_Handler机制原理

Handler通过sendMessage()发送Message到MessageQueue队列;

Looper通过loop(),不断提取出达到触发条件的Message,并将Message交给target来处理;

经过dispatchMessage()后,交回给Handler的handleMessage()来进行相应地处理。

将Message加入MessageQueue时,处往管道写入字符,可以会唤醒loop线程;如果MessageQueue中没有Message,并处于Idle状态,则会执行IdelHandler接口中的方法,往往用于做一些清理性地工作。

android handler的机制和原理_Handler机制原理

Tips:

1.为什么在主线程中使用handler不用调用Looper.prepareMainLooper()和Looper.loop()? 这是因为 ActivityThread 在初始化时已经调用过了,具体见如下源码。

//ActivityThread.java#
           

2.主线程中的Looper.loop()一直无限循环为什么不会造成ANR? 首先要明白ANR的定义,activity超时5s,service超时10s,broadcast超时20s,才会导致Application Not Response。

参考资料:

http://androidxref.com/http://gityuan.com/2015/12/26/handler-message-framework/http://gityuan.com/2015/12/27/handler-message-native/