深入理解android的loop handler message以及thread的关系

 

先由线程说起Thread,线程创建时,为了能够使得线程有一个工作函数,一般有2种方法:重写run方法和创建线程时指定一个实现了Runnable接口的对象实例,当然也可以同时实现这2种方法,因为在Thread类中run方法实现如下

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

而且中的target就是一个Runnable对象。

loop是一个循环体,那么问题来了,循环体,为什么可以循环,在android中一般是一个app启动,最简单的情况就启动进程,在进程创建的同时伴随着一个主线程启动,就是UIthread。在这个ui线程的就是一个消息驱动的工作线程,既然有消息驱动那么对应的消息循环loop,消息发送的handler,和消息体message就需要相互配合了。

framework/base/services/java/com/android/server/am/ActivityManagerService.java在这个文件可以看到相关代码

这个loop类,在实现中有很多静态方法,uithread创建的时候,首先第一步就通过Looper.prepare();方法为当前线程创建looper,并且在线程最后启动这个looper. 这里uithread的looper就有了,

接着继续找handler对象,handler对象的创建,直接new handler,重写了handleMessage方法。这样创建并没有将loop和handler关联上,那么handler怎么知道我的消息该发往哪里?看一眼handler的构造函数,可以在handler的构造函数发想Looper.myLooper(),这个方法获取当前线程对应的loop,将loop中的消息队列获得,以后发送消息的时候,就直接吧消息往消息队列里面放就可以了。handler有了,消息也可以发给loop了

因此一般情况下,使用创建handler的时候,如果不指定loop,那么处理消息的线程就是创建消息的线程。

如果需要消息不在uithread中处理,那么就需要创建新的线程,在线程的run方法运行起来后,需要在run方法中创建looper,并且启动这个looper, 并且保存这个looper的引用;构造handler的时候使用这个loop作为构造函数参数,完成handler构造,使用handler发消息,就可以发送到指定线程了。

需要理解的是线程启动本身没有loop,有一个线程函数run执行,如果创建loop,并运行,因为loop里面存在一个死循环,一直处理消息队列,没消息就等待,有就处理,因此线程会一直在Looper.loop()这个函数运行。

我看了下thread和loop的对应关系存放在ThreadLocal

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值