一、为什么要使用handler
-
当我们要执行某个耗时操作时,如等待五分钟以后更新textView,这个时候不能直接通过创建一个新的线程去实现
-
因为子线程不能进行UI的更新,只有主线程(即UI线程)才可以进行UI的更新
-
但是主线程中不能执行耗时操作,由此引出handler
-
Android中的UI控件不是线程安全的,同时在UI线程中刷新界面,就会出现刷新不同步
-
-
二、什么是handler
-
Handler是SDK中处理异步消息的核心类,主要接受子线程发送的数据,并用此数据配合主线程更信UI
-
官方描述中handler的两个主要作用
-
延时处理消息或者Runnable
-
跨进程通信
-
三、Handler工作机制
-
Message消息,线程间通讯的数据单元
-
如后台子线程处理数据完毕后需要更新UI,可发送一条包含更信信息的Message给UI线程
-
-
MessageQueue消息队列,用来存放通过Handler发布的消息,按照先进先出执行
-
因为同一线程在同一时间只能处理一个消息,因此需要消息队列来保存这些消息
-
Message并不是直接加入MessageQueue的,而是通过与Looper对象相关联的MessageQueue.ldleHandler对象来完成的
-
通过Looper.myQueue()方法获得当前线程的MessageQueue
-
-
Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理
-
Looper循环器,扮演MessageQueue和Handler之间桥梁的角色,循环去除Message Queue中的Message,并交付给相应的Handler处理
-
消息分发的类,主线程创建时会创建默认Looper对象,Looper创建时就会创建MessageQueue
-
默认情况下非主线程并没有与之关联的Looper,可以 通过在线程中调用Looper.prepare()方法获取
-
通过Looper.loop()无限循环地获取并分发MessageQueue中的消息
-
通过Looper.quit()结束循环
-
除此之外,Looper也是程序可以一直运行的原因,让主线程在等其他线程发消息,Looper不断从消息队列拿出消息给主线程,也就是无限去查找是否有消息,没有的话就等待
-
-
注意事项
-
一个Activity只有一个主线程,即UI线程
-
UI线程会自动创建MessageQueue和一个Looper
-
只会存在一个MessageQueue和一个Looper
-
四、补充
1、Looper
-
主线程被创建的时候会初始化一个Looper
-
该Looper通过ThreadLocal保存,也就是说每个线程都保存着自己的ThreadLocal
-
Looper中的loop()方法有一个死循环不断抽取Message
-
为什么有死循环却不会造成卡顿呢?
-
当没有消息来的时候就会wait,有句柄写的时候就被唤醒,进行呢等待
-
所有UI更新操作都通过handler来发消息
-
主线程的队列里没有消息时,就会阻塞在loop的queue.next()里,这时候主线程就会释放CPU资源进入休眠状态,直到下个消息进来唤醒主线程
-
目前是通过pipe管道来写入数据,类似I/O,不占用资源
-
-