Android - Looper / Handler / Message

Looper

prepare()

sThreadLocal.set(newLooper(quitAllowed));

由此可见,Looper是跟ThreadLocal相关的,

很明显说明一个Thread只能有一个Lopper.

     当Looper被初始化时,android.os.MessageQueue会被实例化。


loop()

Looper开始loop之后,就会有一个死循环,来尝试从MQ中取得msg

如果有message,则会调用

msg.target.dispatchMessage(msg);

//P.S.:msg.targetHandler的一个实例

//dispatchMessage最终会有可能调用到HandlerhandleMessage方法


Q:如果在Activitynew一个Handler,那么当用这个handler调用sendMessage方法之后,looper一定会监听到这个message,问题是如果looper的死循环是运行在Activity的主线程中,为什么主线程并没有阻塞呢?

A: [TO BE UPDATED!]  ·[Update 1] Activity 中有一个ActivityThread实例,在这个类的main(String[] args)方法中执行了Looper.prepareMainLooper(), 因此在主线程中有了looper。那么另一个问题来了:ActivityThread跟Activity之间是什么关系呢?

[Update 2] 看来当年并没有理解主线程为什么没有被阻塞,今天重新思考这个问题,发现水比较深。知乎上2016年的回答,我在2015年应该认真研究啊!


====================================================================================

Handler

handler构造

handler的构造中,会尝试找到当前线程中的Looper实例,如果没有Looper实例就会抛出 RuntimeException,一旦有了Looper实例,就有了looper中的MQ,handler就可以把message送到MQ

handler在构造时,会有机会传入一个android.os.CallBack的实例,此CallBack对象会在dispatchMessage的时候被用到


sendMessage(Messagemsg)

当调用了这个方法之后,msg会放到MQ


dispatchMessage(Messagemsg)

Looperloop的时候,如果拿到了msg,就会调用msgtarget(此对象是一个Handler实例)的dispatchMessage方法,

dispatchMessage方法中会优先尝试用msg本身的callBack实例来处理这个messageMessage本身的callBackpackage内可见,也就是说默认作为系统内部使用。我们的程序是没有办法为message来设置callBack的。

如果message本身没有callBack对象实例,那么会尝试用HandlercallBack实例来处理message

如果Handler实例中也没有callBack实例,那么会调用handlerhandleMessage方法来处理message

通常情况下,我们会写一个自己的类来extendsandroid.os.Handler,在自定义的类中,我们需要overridehandleMessage方法,因为在Handler类中的handleMessage方法是空方法,什么逻辑也没有执行


obtainMessage()

我们在需要message的时候,用handlerobtainMessage方法,用这个方法得到的message可以被recycle


SO:Handler链接了Loopermessage,任何一个通过handlersendMessage方法放入looperMQ中的message都会有一个引用指向与msg相关的handler


====================================================================================

Message

成员变量:Handlertarget.

looper执行loop方法的时候就是用的msgtarget对象来执行的dispatchMessage

setDataBundledata)方法

message中保存跟此message相关的数据

SO:MessageHandlerBundle的两个部分的引用



Summary:

Looper: 持有一个MQ,在启动之后会不断的从MQ中取得Message


Handler: 被实例化之后,就有了当前(handler被实例化的)线程中的looper实例(ThreadLocal),通过handler可以往这个LooperMQ中加入要处理的Message


Message: 实例化的时候可以指定与其相关的handler(通过HandlersendMessage等类似方法放到MQ中的Message都会引用到相关的handler)在被从MQ中得到之后,会调用相关handlerdispatchMessage方法


Handler#dispatchMessage: 如果Message本身没有设定callBack(只有系统内部可以为Message设定callBack,我们的程序不能设定,因为MessagecallBack是一个package内可见范围的变量),会尝试调用HandlercallBack对象的方法,如果Handler也没有设定callBack,则最终会调用到HandlerhandleMessage()方法。如果我们实例化的handlerandroid.os.Handler的子类,则实际上最终会调用到我们子类的handleMessage



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值