Handler 学习
在Android系统中,Handler 是常用的异步消息机制。最近在改项目中Lint出来的问题,顺便查了一下Handler的相关资料,记录这个笔记。
要点总结
- 每个线程中只有一个Looper对象,而Looper对象含有一个MessageQueue对象,每个线程可以含有多个handler对象;
- App初始化时,会执行ActivityThread的main方法,在main方法中调用
Looper.prepareMainLooper();
Looper.loop();
进行主线程的Looper初始化;而子线程的Looper初始化需要手动写Looper.prepare()实现(似乎 Android 5.0之后不用手动调用。
Looper的初始化方法中,绑定了当前线程和新建一个MessageQueue对象;
Looper初始化后,需要调用Looper.loop()方法让其运行起来。在主线程中,这个方法会被系统自动调用;子线程中需要自己进行调用。(似乎 Android 5.0之后不用手动调用);
多个Message通过其自身的.next属性形成一个队列(类似与C语言的链表),而MessageQueue对象对此队列进行管理。
每个Handler的handleMessage()方法都是执行在初始化该对象的线程中,而其它方法执行在任意线程;
使用Handler发送消息,最终都会调用带有系统时间的参数的方法,而消息队列中,消息的排序就是根据系统时间进行排序;
-
Handler的post()方法、View的post方法和Activity的runOnUiThread()方法,都是调用了Handler的发送消息方法。
Activity的:
@Override public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } }
View的:
public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); return true; }
Handler的:
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }
Handler的使用容易引起内存泄漏,一般Android Studio会提示你进行弱引用。