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.target是Handler的一个实例
//dispatchMessage最终会有可能调用到Handler的handleMessage方法
Q:如果在Activity中new一个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)
当Looper在loop的时候,如果拿到了msg,就会调用msg的target(此对象是一个Handler实例)的dispatchMessage方法,
在dispatchMessage方法中会优先尝试用msg本身的callBack实例来处理这个message,Message本身的callBack是package内可见,也就是说默认作为系统内部使用。我们的程序是没有办法为message来设置callBack的。
如果message本身没有callBack对象实例,那么会尝试用Handler的callBack实例来处理message
如果Handler实例中也没有callBack实例,那么会调用handler的handleMessage方法来处理message
通常情况下,我们会写一个自己的类来extendsandroid.os.Handler,在自定义的类中,我们需要overridehandleMessage方法,因为在Handler类中的handleMessage方法是空方法,什么逻辑也没有执行
obtainMessage()
我们在需要message的时候,用handler的obtainMessage方法,用这个方法得到的message可以被recycle。
SO:Handler链接了Looper和message,任何一个通过handler的sendMessage方法放入looper的MQ中的message都会有一个引用指向与msg相关的handler。
====================================================================================
Message
成员变量:Handlertarget.
在looper执行loop方法的时候就是用的msg的target对象来执行的dispatchMessage
setData(Bundledata)方法
在message中保存跟此message相关的数据
SO:Message有Handler和Bundle的两个部分的引用
Summary:
Looper: 持有一个MQ,在启动之后会不断的从MQ中取得Message
Handler: 被实例化之后,就有了当前(handler被实例化的)线程中的looper实例(ThreadLocal),通过handler可以往这个Looper的MQ中加入要处理的Message
Message: 在实例化的时候可以指定与其相关的handler(通过Handler的sendMessage等类似方法放到MQ中的Message都会引用到相关的handler)在被从MQ中得到之后,会调用相关handler的dispatchMessage方法
Handler#dispatchMessage: 如果Message本身没有设定callBack(只有系统内部可以为Message设定callBack,我们的程序不能设定,因为Message的callBack是一个package内可见范围的变量),会尝试调用Handler的callBack对象的方法,如果Handler也没有设定callBack,则最终会调用到Handler的handleMessage()方法。如果我们实例化的handler是android.os.Handler的子类,则实际上最终会调用到我们子类的handleMessage