为何用这种消息处理机制
1,子线程不能修改ui界面。
当 App 第一次启动的时候,Android 会同时启动一个对应的主线程(Main Thread),这个
主线程就是 UI 线程,也就是 ActivityThread。UI 线程主要负责处理与 UI 相关的事
件,如用户的按键点击、用户触摸屏幕以及屏幕绘图等。
Android UI操作并不是线程安全的,并且这些操作必须在 UI 线程执行。
现在咱们来回到安卓系统中说的 所有的UI操作都必须放在UI线程中执行,我们假设可以在子线
程更新UI,那么就会出现这样子的一种况:其中一个子线程更新界面还没有完成,另外一个子线
程就又去更新UI了,这样子会造成子UI界面错乱。那么你可能会说,我们可以实行加锁机制啊,
让更新UI的代码不能并发执行。如果每一个子线程都加锁,那么毫无疑问程序的性能将会大大下
降。因此主要的原因总结起来就是两点:
1)为了防止界面错乱
2)为了防止程序性能下降,
因此android不允许在子线程中更新UI。尽管在子线程中发送更新UI的消息,而不用去关心多
线程问题。在主线程的消息队里中采取轮询更新处理。
之间的关系
主线程中 已经初始化了looper对象,并且调用了looper.loop()方法处理消息。所以是主线程中 持有一个l ooper对象,looper对象持有消息队列。
looper.myLooper(); 获取当前进程的looper对象
looper.getMainLooper() 获取主线程的looper对象(也就是当前进程的looper对象)
Handler,作用已经说了。handler的创建必须是在looper已经初始化了,我们在Activity 或者是Fragment 中创建handler对象时,直接new Handler()那是因为这些操作都是在主线程中执行的,主线程已经帮助我们做好了。查看创建handler的源码,可以看到handler是获得了应用的looper(也就是主线程的looper对象),那当然也获得了主线程中looper的消息队列。这样handler 就能将其他线程需要改变UI操作的消息发送到主线程的消息队列中了。
各自的作用
handler 用于发送消息 和处理消息
Looper:持有消息队列,在loop()方法中不断的循环处理消息队列中的消息
消息队列:存放消息的一种数据结构
子线程:子线程只能是没有Looper 对象,如果需要在子线程中处理消息,那么是需要自己在子
线程中 初始化looper,并调用looper.loop()方法进行循环处理这个子线中的消息。
主线程:可参考ActivityThread类中的main()方法,系统已经为我们创建好了looper,并且
也已经帮我们调用了looper.loop()方法,循环处理主线程中的消息