1:谈谈handler,Loop ,Messag三者
- Handler消息辅助类,主要向消息池发送和处理事件
- Message: 传递消息,
- Looper 不断循环执行, 从消息队列中读取消息,按消息分发机制分发给目标者
- handler内部通过Message发送一个消息给looper looper内部通过死循环得到message传递的消息,通过MessageQuen.next得到传递来的Message,最后把message传递给handleCallback(msg);方法.
2:Messagequeue 的数据结构是什么?为什么要用这个数据结构?
MessageQueue内部数据结构不是队列,是一个单链表的数据结构,这样的数据结构对于内部的删除和插入有优势
3: 如何在子线程中创建 Handler?
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Messemsg) {
// process incoming messages here
}
};
Looper.loop();
}
}
4 Handler post 方法原理?
Handler.post(Rnnnable);
new Thread(new Runnable() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
// 在这里进行UI操作
}
});
}
}).start();
5:Looper.loop是一个死循环为什么不会ANR异常呢?
- 什么情况会出现ANR异常.
- 当前事件没有得到处理(可能因为主线程正在处理其他事情,)
- 当前事情正在处理,但是没有及时的到处理结果
查看源码的到结论: ActivityThread#main中
while (true) {
//取出消息队列的消息,可能会阻塞
Message msg = queue.next(); // might block
...
//解析消息,分发消息
msg.target.dispatchMessage(msg);
...
}
- 如果主线程没有looper的运行,就会退出应用, 而ActivityThread#mian中主要就是让消息循环,
- android是事件驱动的looper.loop不断循环接受事件,处理事情,每次的点击都是looper.loop来处理,可以这样说,每一件消息去阻塞了looper.loop.
整个Activity的生命周期都是通过looper.loop来传递. - 而且主线程Looper从消息队列读取消息,当读完所有消息时,主线程阻塞。子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。因此loop的循环并不会对CPU性能有过多的消耗。
6 使用handler中的内存泄露
- 情景一: .在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,Activity自然会在合适的时候被回收。
- 情景二: 如果你的Handler是被delay的Message持有了引用,那么使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行了。
- 情景三:将Handler声明为静态类,静态类不持有外部类的对象,所以你的Activity可以随意被回收。由于Handler不再持有外部类对象的引用,导致程序不允许你在Handler中操作Activity中的对象了。所以你需要在Handler中增加一个对Activity的弱引用(WeakReference)。
static class MyHandler extends Handler
{
WeakReference<Activity> mWeakReference;
public MyHandler(Activity activity)
{
mWeakReference=new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg)
{
final Activity activity=mWeakReference.get();
if(activity!=null)
{
if (msg.what == 1)
{
//....to do somethings
}
}
}
}