版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】android中MessageQueue.IdleHandler的作用是什么
android中MessageQueue.IdleHandler的作用是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。通过Handler向Looper包含的MessageQueue投递Message一般我们比较少接触MessageQueue,其实它内部的IdleHandler接口有很多有趣的用法,首先看看它的定义:简而言之,就是在looper里面的message暂时处理完了,这个时候会回调这个接口,返回false,那么就会移除它,返回true就会在下次message处理完了的时候继续回调,让我们看看它有哪些有趣的用法吧~~一、提供一个android没有的声明周期回调时机如果有这种需求,想要在某个activity绘制完成去做一些事情,那这个时机是什么时候呢?有同学可能觉得onResume()是一个合适的机会,不是可是这个onResume()真的是各种绘制都已经完成才回调的吗?No,toonaive~~你看谷老师说了,onStart是用户可见,onResume是用户可交互,谷老师可没说onResume是绘制完成吧~那么android那些耗时的measure,layout,draw是在什么时候执行的呢?它们跟onResume()又有何关系呢?让我们先来看看源码吧~1.ActivityThread.java我们知道app的进程其实是ActivityThread,那么activity的生命周期自然是它来执行了,performResumeActivity就是回调onResume了,我们继续看wm.addView方法,这个ViewManager是一个接口,其实现者是WindowManagerImpl2.WindowManagerImpl.java这个mGlobal是WindowManagerGlobal对象,我们继续3.WindowManagerGlobal.java这里我们new出了ViewRootImpl对象,我们知道这个对象就是androidview的根对象了,负责view绘制的measure,layout,draw的巨长的方法performTraversals就是这个类的,我们继续看setView方法4.ViewRootImpl.java这个函数调用了关键方法requestLayout(),我们继续跟踪,顺便说下,后面一连串的BadTokenException就是我们常常遇到的dialog相关抛出的,也有些特殊场景也会出这个异常,可以到这里查看线索。调用了scheduleTraversals,从名字就能看出来了吧:它往Choreographer里面post了一个runnable,这个Choreographer是android负责帧率刷新相关的东西,我们暂时可以不关注它,可以理解为往主线程post一个消息是一样的,顺便说下这个Choreographer可以做帧率检测相关的东西,,可以用于卡顿检测什么的···我们看这个runnable果然是去执行了那个巨长无比的函数performTraversals函数,现在我们可以总结下流程了:结论:所以如果我们想在界面绘制出来后做点什么,那么在onResume里面显然是不合适的,它先于measure等流程了,有人可能会说在onResume里面post一个runnable可以吗?还是不行,因为那样就会变成这个样子所以你的行为一样会在绘制之前执行,这个时候我们的主角IdleHandler就发挥作用了,我们前面说了,它是在looper里面message暂时执行完毕了就会回调,顾名思义嘛,Idle就是队列为空的意思,那么我们的onResume和measure,layout,draw都是一个个message的话,这个IdleHandler就提供了一个它们都执行完毕的回调了,大概就是这样说了这么多,那么现在获取到这个时机有什么用呢?look!!这个是我们地图的公交详情页面,进入之后产品要求左边的页卡需要展示,可以看到左边的页卡是一个非常复杂的布局,那么进入之后的效果可以明显看到头部的展示信息是先显示空白再100毫秒左右之后才展示出来的,原因就是这个页卡的内容比较复杂,用数据向它填充的时候花了较长时间,代码如下:可以看到这个detailView就是这个侧滑的页卡了,填充里面的数据花了90ms,如果这个时间是用在了界面view绘制之前的话,就会出现以上的效果了,view先是白的,再出现,这样就体验不好了,如果我们把它放到IdleHandler里面呢?代码如下:效果是这样的:看出不同了吗?顶部的页卡先展示出来了,这样体验是不是会更好一些呢。虽然只有短短90ms,不过我们做app也应该关注这种细节优化的,是吧~这个做法也提供了一种思路,android本身提供的activity框架和fragment框架并没有提供绘制完成的回调,如果我们自己实现一个框架,就可以使用这个IdleHandler来实现一个onRenderFinished这种回调了。二、可以结合HandlerThread,用于单线程消息通知器我们先思考一个问题,如果有一个model数据管理模块,怎么设计?比如地图的收藏模块的model部分。就是下面这个图的小星星:它原来的model设计大概是这个样子的:由于这个model是单例的,而且是多线程可以访问的,所以它的增删改查都加上了锁,而且由于外部访问需要遍历有哪些收藏点,所以外部遍历列表也需要加锁,大概是这样的:因为是多线程可访问的,如果遍历不加锁的话,其他线程删除了一个收藏,就会crash的,原来的这样设计有几个不好的地方:1.外部使用者需要关系锁的使用,增加了负担,不用还不安全2.如果在主线程加锁的话,可能另一个线程执行操作会阻塞主线程造成anr总之,多线程代码就是容易出错,而且真的出错的时候查起来太费劲了,目前收藏夹模块就有N多bug,所以我想用单线程来解决这个问题,由于model层的访问需要数据库和网络等,所以需要异步线程,那么单线程队列+异步线程,首先想到的就是HandlerThread,大概架构如下:现在,我们把原来多线程的逻辑改到了单线程里面,各种收藏的model共用一个HandlerThread,这样我们增删改查都不用加锁了,出错几率大大减小,而且这种model的设计有点类似插件的意思,可以很方便的增加其他收藏。Ok,那么跟我们的主题IdleHandler有什么关系呢?思考这样一个问题,地图上的小星星需要实时更新,也就是model的任何变化都需要显示到地图上,那么收藏的小星星就应该作为model的观察者,以前的做法是向收藏model注册监听,在每一个增删改查操作后都对观察者回调,大概是这样:这样有一个小小的问题,就是如果有一个操作生成10个快速连续的增删改查操作,那么我们的UI就会收到10次回调,而这种场景下我们其实只需要最后一次回调就够了,中间操作其实不用刷新UI的。那么现在改成单线程模型,我们又该如何处理这个问题呢?当然我们也能在每个post到异步线程的runnable里面去回调观察者,但这样未免不够优雅,所以这个时候IdleHandler不就又可以发挥作用了吗?它是在消息暂时处理完的时候回调的呀,不是很符合我们的时机么,对吧?就是这个样子了,这里为什么不用第一个场景下的Looper.m
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 延安大学《英语测试与评价》2022-2023学年第一学期期末试卷
- 铁路信号设备招标合同三篇
- 烟台大学《数据结构课程设计》2021-2022学年第一学期期末试卷
- 三年级数学(上)计算题专项练习附答案集锦
- 四年级数学(四则混合运算带括号)计算题专项练习与答案汇编
- 五年级数学(小数四则混合运算)计算题专项练习及答案
- 徐州工程学院《美术(Ⅱ):美术创作》2021-2022学年第一学期期末试卷
- 学期教学课程工作计划
- 主管职能与责任的全面分析计划
- 公关活动策划与实施方案计划
- 2024年中国电信广东公司招聘笔试参考题库含答案解析
- 2024年中国华电集团招聘笔试参考题库含答案解析
- 教学课件:《新时代新征程》
- 2023年整车NVH分析工程师年度总结及来年计划
- 废气治理设施运行管理规程、制度
- 闲置铺面招租经营方案
- 2023年版劳动合同法全文
- 质量保证体系评价-评价表(ASES-ver.1.6)
- 空调维保投标方案(技术方案)
- 办事依法,遇事找法,解决问题用法
- 销售管理系统程序设计-C语言
评论
0/150
提交评论