首页 > 代码库 > android handle详解2 主线程给子线程发送消息

android handle详解2 主线程给子线程发送消息

按照android handler详解分析的原理我们可以知道,在主线程中创建handle对象的时候,主线程默认创建了一个loop对象使用threalocal函数将loop对象和主线程绑定。

我们能不能在子线程中创建一个loop对象和子线程绑定了实际上是可以的

技术分享

 

这样我们就在子线程中创建了一个looper对象,将looper对象和子线程绑定了,在子线程中执行Loop.loop()函数的内部是开启了一个死循环对消息队列中的消息进行遍历,所以子线程是永远不会退出的。

当我们在主线程中调用获得subHandler对象就可以给子线程发送了消息了

技术分享

子线程收到了消息之后会在handlMessage中弹出一个Toast

这里为啥能够在子线程中弹出Toast了,因为在子线程中存在looper对象和该子线程绑定。正常情况下之所以只能在主线程中弹出toast,是因为主线程会有一个默认的looper对象和主线程绑定。现在我们在子线程中创建了一个looper对象,所以就能够在子线程中弹出一个toast

总结:

如果一个线程要处理消息,那么它必须拥有自己的Looper,很明显的一点就是,我们要在子线程中调用Looper.prepare() 为一个线程开启一个消息循环,默认情况下Android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。) Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。 然后通过Looper.loop() 让Looper开始工作,从消息队列里取消息,处理消息。

 上面的代码存在内存泄露,为啥了因为在线程中Loop.loop()方法内部是开启了一个死循环来对消息队列进行遍历,所以即使activity退出了,该线程还是不会退出,线程里面toast存在MainActivity的引用,就会导致activity退出了,但是activity在线程中的引用还存在,导致内存泄露

如何解决了,我们应该在activity的onDestory中退出的时候,停止死循环变量消息队列,可以调用looper对象的quit函数,所以首先我们需要得到该looper对象

技术分享

 

其次在activity的onDestory中调用quit函数

技术分享

 

是不是相当的经典

android handle详解2 主线程给子线程发送消息