View.post() 不靠谱的地方你知道多少
一、前言
在Android开发中,View.post()方法常被用于将任务投递到主线程执行,其背后通过Handler进行实现,为我们省去了创建Handler对象的繁琐过程。从Android 7.0(API level 24)开始,这一方法似乎变得不那么可靠了。你可能会发现通过post()方法投递的Runnable任务可能永远不会被执行。
二、View.post()在Android 7.0的变化
1. 方法差异:从源码层面分析,Android 7.0对View.post()方法的改动主要体现在当View的mAttachInfo为null时,执行的逻辑发生变化。相较于API level 23及以下版本,API level 24中的实现会通过getRunQueue().post(action)的方式处理,而API level 23及以下则会通过ViewRootImpl.getRunQueue().post(action)。
2. API 23及以下版本的细节:
- ViewRootImpl是Activity的ViewTree的根节点的实例,负责管理DecorView和ViewTree。每个ViewRootImpl实例都承载着一个用于处理Runnable任务的队列sRunQueues,这是一个静态变量,意味着在App的生命周期内,这个消息队列是共享的。
- 在API 23及以下版本中,通过ViewRootImpl的getRunQueue().post()方法添加任务时,会将这些任务包装成HandlerAction对象并放入mActions这个ArrayList中。这些任务何时被消费掉呢?它们会在executeActions()方法中被处理。
- executeActions()方法是在TraversalRunnable的doTraversa()方法中调用的。TraversalRunnable则通过Choreographer的postCallBack()方法进行循环调用。Choreographer通过发送MSG_DO_SCHEDULE_CALLBACK类型的消息进行循环调用,间隔与VSync同步。这意味着在API 23以下的设备上,executeAction()方法会被循环调用,只要存在未执行的Runnable任务,它们会立即被执行。在这些设备上,View.post()方法是可靠的。
介绍Api24细节:关于View.post()的隐秘差异
当我们深入Api24的细节时,有一个特别引人注目的点值得我们关注——那就是View.post()方法的实现。在这个版本中,该方法通过操作一个HandlerActionQueue对象来实现其功能。
其内部结构与Api23颇为相似,维护着一个名为mActions的HandlerAction数组。关键的消费动作由executeActions()方法完成。这个方法究竟在何时被触发呢?追查下去,你会发现它在View的dispatchAttachedToWindow()方法中被调用。
问题的关键在于,在Api24及其以上版本中,executeActions()方法的触发仅限于dispatchAttachedToWindow()方法。而这个方法只有在View通过addView()等方法加入到ViewGroup中时才会被调用。这意味着,在Layout布局中的控件不会触发addView()方法,因此它们永远无法执行executeActions()方法。这就是导致Api24下View.post()表现不一致的原因。
小结:
View.post()方法在不同版本的Android系统中表现不同,其根本原因在于Api23和Api24中executeActions()方法的调用时机存在差异。当View还没有mAttachInfo对象时,其表现尤为明显。
在使用View.post()方法时,我们需要谨慎选择使用场景,确保在View已经显示后再调用此方法(此时mAttachInfo已经不为空)。为了避免潜在的问题,我们可以选择使用Handler.post()方法来替代。
以上所述是长沙网络推广团队为大家揭示的View.post()的使用陷阱,希望能对大家有所帮助。如有任何疑问,请随时留言,长沙网络推广团队会及时回复。感谢大家对狼蚁SEO网站的支持与关注!
这段文本保持了原文的风格和特点,同时进行了语言的优化和细节的丰富,使其更加生动、吸引人。
编程语言
- View.post() 不靠谱的地方你知道多少
- vue 插件的方法代码详解
- 移动适配的几种方案(三种方案)
- 详解mysql中的冗余和重复索引
- PHP中使用数组指针函数操作数组示例
- angular.js+node.js实现下载图片处理详解
- js 动态生成json对象、时时更新json对象的方法
- 利用Vue-draggable组件实现Vue项目中表格内容的拖拽
- 详解在vue-cli中使用路由
- php实现专业获取网站SEO信息类实例
- PHPExcel笔记, mpdf导出
- WMV网页播放器参数中文详解
- 详解jenkins自动化部署vue
- jQuery Ajax Post 回调函数不执行问题的解决方法
- 使用javascript函数编写简单银行取钱存钱流程
- asp.net操作xml增删改示例分享