很久以前有Activity.onResume就是界面可见的说法,这种说法毫无疑问是不准确的。
问题是:
- Activity.onCreate 和 Activity.onResume,在调用时间上有差别么?可以从Message调度去考虑。
- 有没有一个合理的时机,让我们认为Activity 界面可见了?
更多问答 >>
-
每日一问 今天考察下 Fragment 相关两个不常见 API
2020-03-19 00:55 -
每日一问 LifeCycle 对于 Lifecycle.Event 为啥不直接分发,而是通过 Lifecycle.State 中转?
2020-04-19 14:42 -
每日一问 ViewPager 这个流传广泛的写法,其实是有问题的!
2020-03-26 00:10 -
2020-03-23 23:45
-
每日一问 | 自定义控件测量模式真的和 match_parent,wrap_content 一一对应吗?
2020-03-30 01:01 -
每日一问 RecyclerView卡片中持有的资源,到底该什么时候释放?
2020-03-10 21:11 -
每日一问 | 事件到底是先到DecorView还是先到Window的?
2020-03-03 23:25 -
每日一问 Android有个GestureDetector很好用?那么你知道它内部是如何实现的吗?
2020-03-02 23:56 -
每日一问 很多时候我们说单例实现方式会提到「枚举实现」,那么枚举底层是如何实现的呢?
2020-02-23 22:18 -
2020-02-02 17:17

仅从启动Activity角度来看,onCreate / onStart / onResume 都是一个message里面的逻辑,具体可以看ActivityThread里面的 handleLaunchActivity 方法:
非要强调精确的可见回调时机很难,因为ViewRootImpl里将布局执行完draw之后还需要提交到surfaceflinger合成,这里已经脱离了应用进程;不过阿里提出了一种通过录屏+图片识别来获取启动时间的方案,从另一种角度来满足需求;但是仅从应用开发角度来看,选择
onWindowfocusChanged的首次回调是一个比较精准的可见时机,整个Activity启动的大致回调流程如下:对于我们设置的布局来说,经历了如下几个阶段:
至于 onWindowFocusChanged,得从第3步说起,在setView方法中,紧接在 requestLayout 之后的逻辑就是向WMS通过binder发起添加window的过程,WMS完成操作后会把windowFocusChanged的事件回调给应用进程,ViewRootImpl在把该事件分发给DecorView,而DecorView重载了View的 onWindowFocusChanged 方法,内部最终将消息通过接口回传给了Activity的onWindowFocusChanged。
从这里看到似乎是先回调 onWindowFocusChanged 再执行Traversals,其实不然,进程间通信是承载在双方进程的binder线程池之上的,因此消息从WMS回到应用线程还需要通过handler抛向主线程,而前一步的scheduleTraversals在安排任务之前会向主线程消息队列插入一个异步屏障消息,并且在 performTraversals时才会移除该消息,期间所有抛向队列的同步消息都被阻塞,包括 windowFocusChanged 事件,因此实际情况是先Traversals再focusChanged。
因此我们可以说windowFocusChanged可以作为一个比较精准的可见时机。
第四步给了我之前的困惑的一个思路。我写的截全屏处理逻辑总是搞出两个图片。 点赞
写的都挺赞同,onresum后申请v-sync, 在接下来收到v-sync的16.6ms中,performDraw方法执行结束(此时cpu可以执行其他msg了,比如windowFocusChanged ...查看更多
写的都挺赞同,onresum后申请v-sync, 在接下来收到v-sync的16.6ms中,performDraw方法执行结束(此时cpu可以执行其他msg了,比如windowFocusChanged ) + render线程生成buffer。 那我想问,surfaceflinger是再下一个v-sync才开始合成window中的surface,所以windowFocusChanged调用的时候屏幕应该看不到view啊,顺便问一句,window能收到input事件,是不是也是windowFocusChanged调用的时候。 谢谢
Activity的界面是在onResume之后才开始进行绘制的,onWindowFocusChanged回调里能确认UI可见可操作。
或者利用Handler机制。View.post个消息 也能达到效果
修复了问题没放出来就被你发现的 bug...
这种提交代码的口吻
合理的时机认为Activity界面可见可以使用IdleHandler
我觉得你还是没有完全搞懂IdleHandler,如果你的界面有其他消息还在执行,你的IDleHandler什么时候被触发回调都是个问题,个人同意楼上的onWindowFoucsChanged方法的理解 ...查看更多
我觉得你还是没有完全搞懂IdleHandler,如果你的界面有其他消息还在执行,你的IDleHandler什么时候被触发回调都是个问题,个人同意楼上的onWindowFoucsChanged方法的理解
虽然就是界面可见是不准确的,但是这么说也是有一定原因的。
onresume是生命周期可见之前最后一个回调,所以你要在界面恢复可见时做一些操作,一般都是在这。或者说这么思考,为什么你的某些代码要放在onresume里面不放在oncreate里面。