【读书笔记】Android Handler和Looper流程
2016-01-04 14:46
393 查看
最近在阅读《Android系统源代码情景分析》,记录一下Android Handler和Looper流程。
Looper由ActivityThread.main()创建并启动消息循环,ActivityThread.main()代码如下:
调用Looper.prepareMainLooper()之后,创建静态的的Looper对象sMainLooper,并将Looper对象存放到ThreadLocal<Looper>里面。在不同线程下可以通过调用Looper.myLooper()创建自己的消息循环其实就是利用ThreadLocal<Looper>来实现的。
Looper的准备流程图如下:
当进入Looper.loop()之后,会读取MessageQueue里面的消息,如果消息队列为空则睡眠等待,直到通过Handler.sendMessage()将Message放入到MessageQueue才会唤醒,流程如下:
将Message放入到MessageQueue之后,Looper.loop()则会取出Message,然后通过msg.target.dispatchMessage(msg)进入到处理消息流程:
如此就会进入到Handler.handleMessage()里面,平时Handler的使用就是覆写Handler.handleMessage()来处理消息,调整UI的。
PS:
1、new Handler()无参构造函数默认调用Looper.myLooper(),如果在另外的子线程中调用而没有先调用Looper.prepare()则会抛出RuntimeException("Can't create handler inside thread that has not called Looper.prepare()")异常;
如果在子线程中也想调用主线程中的消息循环,那么必须通过new Handler(Looper.getMainLooper())传递主线程的Looper;
2、由于Looper.prepareMainLooper()已经在ActivityThread中调用了,如果在其他地方调用则会出错,因此Looper.prepareMainLooper()不应该被调用;
3、如果想要使用与界面无关的消息循环,建议使用HandlerThread;
4、如果想要使用与界面有关的消息循环,建议使用AsyncTask。
Looper由ActivityThread.main()创建并启动消息循环,ActivityThread.main()代码如下:
public static void main(String[] args) { ... //创建Lopper Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } //为AsyncTask指定MainLooper,使得AsyncTask的回调函数运行在主线程上 //此代码在5.1之后被移除 AsyncTask.init(); //开启消息循环 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
调用Looper.prepareMainLooper()之后,创建静态的的Looper对象sMainLooper,并将Looper对象存放到ThreadLocal<Looper>里面。在不同线程下可以通过调用Looper.myLooper()创建自己的消息循环其实就是利用ThreadLocal<Looper>来实现的。
Looper的准备流程图如下:
当进入Looper.loop()之后,会读取MessageQueue里面的消息,如果消息队列为空则睡眠等待,直到通过Handler.sendMessage()将Message放入到MessageQueue才会唤醒,流程如下:
将Message放入到MessageQueue之后,Looper.loop()则会取出Message,然后通过msg.target.dispatchMessage(msg)进入到处理消息流程:
如此就会进入到Handler.handleMessage()里面,平时Handler的使用就是覆写Handler.handleMessage()来处理消息,调整UI的。
PS:
1、new Handler()无参构造函数默认调用Looper.myLooper(),如果在另外的子线程中调用而没有先调用Looper.prepare()则会抛出RuntimeException("Can't create handler inside thread that has not called Looper.prepare()")异常;
如果在子线程中也想调用主线程中的消息循环,那么必须通过new Handler(Looper.getMainLooper())传递主线程的Looper;
2、由于Looper.prepareMainLooper()已经在ActivityThread中调用了,如果在其他地方调用则会出错,因此Looper.prepareMainLooper()不应该被调用;
3、如果想要使用与界面无关的消息循环,建议使用HandlerThread;
4、如果想要使用与界面有关的消息循环,建议使用AsyncTask。
相关文章推荐
- 打开 Android Studio unable to access android sdk add-on list问题
- 图文详解Andorid中用Shape定义GradientDrawable
- Android中把View转换成bitmap,再缓存到sd卡
- android 自定义Log日志工具
- 广播实现的方式
- Android防截屏小技巧
- 2015年 android 白皮书
- android pbap协议翻译
- 基于RxJava、RxAndroid的EventBus实现
- Android font-awesome 4.2 icons png(包含holo-light和holo-dark)
- android 在函数中使用return,让后面的代码不再执行
- android常见的库文件
- android常见的库文件
- Android Studio 手机运行时中文乱码
- Android编程使用ListView实现数据列表显示的方法
- android 获取全局context
- android-Adding Animations
- Android wav头添加
- Android APK反编译详解(附图)
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系