Handler:
1. handler 作用:用于子线程更新主线程 UI,发送消息和处理消息。
2. handler 四要素:
(1)消息 message
(2)消息队列 messageQueue(优先级队列,按执行时间进行排序),用来存放Handler发送过来的消息,内部通过单链表的数据结构来维护消息列表,等待Looper的抽取。
(3)looper 从消息队列中取消息, 主线程默认创建的。通过Looper.loop()不断地从MessageQueue中抽取Message,按分发机制将消息分发给目标处理者。
(4)Handler(处理者):负责Message的发送及处理。通过 Handler.sendMessage() 向消息池发送各种消息事件;通过 Handler.handleMessage() 处理相应的消息事件。
3. handler使用步骤:
4. 在主线程中定义一个handler,重写里面的handleMessage方法
private Handler mhandler=new Handler()
{
public void handlerMessage(android.os.message msg)
{
String content=(String)msg.obj;
setText(content);//更新UI信息
}
};
5. 用主线程中创建的handler 对象,在子线程中发送更新UI的消息
Message msg=new Message();
string content="hello"
msg.what=1;//消息id int 类型数据
备注:大小写转换快捷键 ctrl+shift+X Y
msg.obj=string;;
handler.sendMessage(msg)
handler 主要函数:
handler 常见的问题?
1.一个线程可以有几个handler?
可以有多个
2.一个线程有几个looper? 如何保证?
只有一个looper, 通过ThreadLocalMap,局部线程map, 将线程名(key)和looper(value)ThreadLocal 是唯一的。
3.handler 内存泄露的原因?为什么其它内部类没有这个问题?
原因:匿名内部类持有外部类对象。handler默认持有Mainactivity 对象,message持有handler对象(msg.target=this),messagequeue 持有message。当消息不能及时处理,会造成内存泄露。
解决办法:静态内部类,不持有外部对象;软引用;
4.为何主线程可以new handler?如果想要在子线程中new handler 要做哪些准备?
主线程默认有一个looper。在子线程中创建looper.looper.prepare() 和 looper.loop();
5. 子线程中维护的looper ,消息队列没有消息的时候的处理方案是什么,有什么用?
消息队列中没有消息时,queue.next()中会阻塞掉(nativepollonce),要想退出looper 需要唤醒,然后释退出looper. 调用looper.quit(),在quit()方法中会首先mQuitting=true,然后移除消息队列中所有的消息,nativewake()唤醒线程.
6. 既然可以存着多个handler 往消息队列中添加数据(发送消息时各个handler可能在不同的线程中),内部如何保证线程安全的?
加锁
7. looper 死循环为什么不会导致应用卡死?
享元设计模式