博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【读书笔记】Android Handler和Looper流程
阅读量:5291 次
发布时间:2019-06-14

本文共 1587 字,大约阅读时间需要 5 分钟。

最近在阅读《Android系统源代码情景分析》,记录一下Android Handler和Looper流程。

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。

转载于:https://www.cnblogs.com/alexthecoder/p/5098905.html

你可能感兴趣的文章
git回退到某个版本并提交
查看>>
查看oracle数据库的连接数以及用户
查看>>
简单几行js实现tab选项切换效果
查看>>
关于更改滚动条样式
查看>>
【数据结构】栈结构操作示例
查看>>
中建项目环境迁移说明
查看>>
三.野指针和free
查看>>
VIO的Bundle Adjustment推导
查看>>
activemq5.14+zookeeper3.4.9实现高可用
查看>>
asp.net FileUpload控件文件格式的判断及文件大小限制
查看>>
angular(1.5.8)
查看>>
h5的video标签支持的视频格式
查看>>
TCP/IP详解学习笔记(3)IP协议ARP协议和RARP协议
查看>>
简单【用户输入验证】
查看>>
学android:直接用jdk来helloworld
查看>>
Access Jira RESTful API by cURL
查看>>
python tkinter GUI绘制,以及点击更新显示图片
查看>>
Spark基础脚本入门实践3:Pair RDD开发
查看>>
HDU4405--Aeroplane chess(概率dp)
查看>>
RIA Test:try catch 对 Error #1009 (无法访问空对象引用的属性或方法)的处理
查看>>