处理程序是Android中提供的一种异步回调机制,也可以理解为线程间的消息机制。为了避免ANR,我们通常会把一些耗时操作(比如:网络请求,I/O操作,复杂计算等)放到子线程中去执行,而当子线程需要修改UI时则子线程需要通知主线程去完成修改UI的操作,则此时就需要我们使用处理器机制来完成子线程与主线程之间的通信。
1。处理程序的一般使用步骤h5>
在明确了Android中只有主线程能修改UI界面,子线程执行耗时操作的前提后,下面一起来学习下处理器的使用步骤。
-
<李>
在主线程中创建处理器实例,并且重写handlerMessage方法。
<代码>私人处理程序处理程序=new处理程序(){ @Override 公共空间handleMessage(消息味精){ 开关(msg.what) { 案例1://执行相关修改UI的操作 打破; } } };代码>李> <李>
子线程中获取处理程序对象,在需要执行更新UI操作的地方使用处理器发送消息
<代码>消息味精=Message.obtain (); 味精。obj=澳谌荨? 味精。=1;//发送消息给处理程序 handler.sendMessage(味精);代码>李> <李>在handlerMessage方法中里的切换面,根据情况下不同的常量执行相关操作李>
以上只是处理程序的一种使用方式,由于本文的重点是探究Handlerde原理,故其他使用方式这里不重点介绍。
2。重要类的职责h5>
在深入了解处理程序机制原理之前,我们应该明确在处理器机制中几个重要类的职责。
-
<李>处理程序:负责发送处理消息李>
<李> MessageQueue:消息队列,负责存储消息李>
<李>信息:具体发送的消息李>
<李>电影:负责循环取出消息给处理程序处理李>
<李> ThreadLocal:用于线程间的数据隔离,在每个线程中存放各自对应的电影李>
3。处理程序机制原理h5>
<李>
每个处理程序都会关联一个消息队列,消息队列又是封装在电影对象中,而每个电影又会关联一个线程。这样处理程序,消息队列,线程三者就关联上了。
李>
<李>
处理程序是一个消息处理器,将消息发送给消息队列,然后再由对应的线程从消息队列中逐个取出,并执行。
李>
<李>默认情况下,消息队列只有一个,也就是主线程的消息队列,该消息队列通过Looper.prepareMainLooper()方法创建,最后执行Looper.loop()来循环启动消息。李>
引用>
以上叙述可能有点空洞、下面我们结合源码一起来理解:
<编辑> 3.1处理程序是如何关联消息队列和线程的? 编辑>
我们首先看处理器默认的构造函数:
<代码>公共处理程序(回调的回调,布尔异步){//代码省略
mLooper=Looper.myLooper();//获取尺蠖
如果(mLooper==null) {
把新的RuntimeException (
“不能创建处理程序内部线程没有叫Looper.prepare () ");
}
mQueue=mLooper.mQueue;//通过电影对象获取消息队列
mCallback=回调;
mAsynchronous=异步;
}//获取电影对象
公众最终尺蠖getLooper () {
返回mLooper;
}代码>
从处理器的构造函数中我们可以发现,处理程序在初始化的同时会通过Looper.getLooper()获取一个电影对象,并与电影进行关联,然后通过电影对象获取消息队列。那我们继续深入到电影源码中去看Looper.getLooper()是如何实现的。
<代码>//初始化当前线程尺蠖
公共静态孔隙prepareMainLooper () {
准备(假);
同步(Looper.class) {
如果(sMainLooper !=null) {
把新的IllegalStateException(“主要的电影已经准备。”);
}
sMainLooper=myLooper ();
}
}//为当前线程设置一个电影
私有静态空准备(布尔quitAllowed) {
如果(sThreadLocal.get () !=null) {
把新RuntimeException(“只有alt="解析Android中处理程序机制原理">
关于处理器机制补充如下几点:
<李>处理程序创建消息时用到了消息池,在创建消息时会先从消息池中去查询是否有消息对象,如果有,则直接使用消息池中的对象,如果没有,则创建一个新的消息对象。李>
<李>使用ThreadLocal的目的是保证每一个线程只创建唯一一个电影。之后其他处理程序初始化的时候直接获取第一个处理程序创建的电影李>
解析安卓系统中处理器机制原理
-
<李>
每个处理程序都会关联一个消息队列,消息队列又是封装在电影对象中,而每个电影又会关联一个线程。这样处理程序,消息队列,线程三者就关联上了。
李> <李>处理程序是一个消息处理器,将消息发送给消息队列,然后再由对应的线程从消息队列中逐个取出,并执行。
李> <李>默认情况下,消息队列只有一个,也就是主线程的消息队列,该消息队列通过Looper.prepareMainLooper()方法创建,最后执行Looper.loop()来循环启动消息。李>以上叙述可能有点空洞、下面我们结合源码一起来理解:
<编辑> 3.1处理程序是如何关联消息队列和线程的? 编辑>我们首先看处理器默认的构造函数:
<代码>公共处理程序(回调的回调,布尔异步){//代码省略 mLooper=Looper.myLooper();//获取尺蠖 如果(mLooper==null) { 把新的RuntimeException ( “不能创建处理程序内部线程没有叫Looper.prepare () "); } mQueue=mLooper.mQueue;//通过电影对象获取消息队列 mCallback=回调; mAsynchronous=异步; }//获取电影对象 公众最终尺蠖getLooper () { 返回mLooper; }代码>
从处理器的构造函数中我们可以发现,处理程序在初始化的同时会通过Looper.getLooper()获取一个电影对象,并与电影进行关联,然后通过电影对象获取消息队列。那我们继续深入到电影源码中去看Looper.getLooper()是如何实现的。
<代码>//初始化当前线程尺蠖 公共静态孔隙prepareMainLooper () { 准备(假); 同步(Looper.class) { 如果(sMainLooper !=null) { 把新的IllegalStateException(“主要的电影已经准备。”); } sMainLooper=myLooper (); } }//为当前线程设置一个电影 私有静态空准备(布尔quitAllowed) { 如果(sThreadLocal.get () !=null) { 把新RuntimeException(“只有alt="解析Android中处理程序机制原理">关于处理器机制补充如下几点:
-
<李>处理程序创建消息时用到了消息池,在创建消息时会先从消息池中去查询是否有消息对象,如果有,则直接使用消息池中的对象,如果没有,则创建一个新的消息对象。李>
<李>使用ThreadLocal的目的是保证每一个线程只创建唯一一个电影。之后其他处理程序初始化的时候直接获取第一个处理程序创建的电影李>