Android面试线程—Handler

定义:

用于线程间通讯,主要接受子线程发送的数据, 并用此数据配合主线程更新UI。(注意:Handler只能在主线程创建!!!)

为什么要用Handler:

UI线程不能耗时操作,超过5s会报ANR异常,所以我们需要开启子线程做耗时操作,但是线程间不能直接通讯,所以Android为我们提供了Handler用于线程间通讯。(广播也可以线程间通讯)

Handler发送消息的方法:(在子线程发送消息,主线程创建Handler)
两种消息类型:runnable和message(多线程实现方式implements Runnable或 extends Thread)

post(Runnable)、postAtTime(Runnable,long)、

postDelayed(Runnable long)、sendEmptyMessage(int)

sendMessage(Message)、sendMessageAtTime(Message,long)

sendMessageDelayed(Message,long)

Handler、Looper、MessageQueue示意图:

Handler原理图

这里注意几点:looper循环拿到MQ的消息;发送和接受消息都是通过Handler;

looper、MQ和Handler都在主线程。

注意:某些情况下会出现内存泄露

原理:非静态内部类持有外部类匿名应用可能会造成内存泄露;

解决方法:非静态内部类改为静态内部类;(原理:静态内部类不持有外部类的引用)

                  使用弱引用;


下面来看看源码:

首先看Handler构造方法,这创建了looper和MQ,在进入looper中你会发现三者是在同一个线程。

(sendMessage()----> enqueueMessage()方法表示插入消息)

Handler构造方法

looper的创建,这里的ThreadLocal是java方法,任意线程调用ThreadLocal其get()和set()方法都是在调用线程。

如:这里调用是UI线程,所以get和set就在UI线程。

looper创建方法

这里可以看到prepare()中 ThreadLocal添加looper

looper创建准备方法

这里是looper中的loop()方法  消息通过这个死循环来轮训消息  当没有消息时 会自动阻塞 (Linux 会开启一个管道用于管理阻塞

通知红框内,可以看到消息分发出去是通过dispatchMessage发送的,如果进入msg中,你会发现target这个变量其实就是Handler,所以looper是通过Handler发送消息的

looper中的loop()方法

onPostExecute


最后来看看Handler中的dispatchMessage方法,这里可以看到最终数据又回到handleMessage中。至此行程了一个循环

looper取出消息分发方法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容