Looper通过prepare()方法创建looper,并将其保存在sThreadLocal中。通过looper.loop开启循环,开始消息分发。
handler的dispatchMessage(msg)
handler引起内存泄露的原因及处理办法:原因:静态内部类持有外部类的匿名引用,导致外部act无法释放。
解决办法:handler内部持有外部act的弱引用,并把handler改为静态内部类;在act的onDestroy()方法中调用mHandler.removeCallback();
Handler类内部有mLooper和mQueue两个成员变量,分别指向一个Looper对象和一个MessageQueue对象。Handler还有sendMessage()和handleMessage() 两个成员函数。其中sendMessage()方法用来向成员变量mQueue(消息队列)发送一个消息;而handleMessage用来处理这个消息,并且它是在与成员变量mLooper所关联的线程中被调用的。
异步消息处理流程:1.UI线程中创建一个handler对象,并重写handleMessage()方法。
2.当子线程中需要进行UI操作是,创建一个Mesage对象,并通过Handler将这条消息发送出去。
3.这个消息会进入MessageQueue,等待被处理。
4.Handler的mLooper会尝试从MQ中取出待处理消息,经由分发器dispatcher分发回Handler的handleMessage()方法来处理。
由于Handler的实例在UI线程中创建,所以handleMessage方法也会在UI线程中运行,由此更新UI。
HandlerThread:handler+thread+looper。能够新建拥有Looper的线程。这个Looper能够用来新建其他的Handler。
什么时候使用HandlerThread?
必然是执行耗时操作。举个例子,数据实时更新,我们每10秒需要切换一下显示的数据,如果我们将这种长时间的反复调用操作放到UI线程中,虽说可以执行,但是这样的操作多了之后,很容易会让UI线程卡顿甚至崩溃。
于是,就必须在子线程中调用这些了。
HandlerThread继承自Thread,一般适应的场景,便是集Thread和Handler之所长,适用于会长时间在后台运行,并且间隔时间内(或适当情况下)会调用的情况,比如上面所说的实时更新,多网络请求,多文件I/O,子线程完成多个下载任务等。
关键方法有run()和getLooper()。run方法中的逻辑在子线程中运行。