冷启动结束的时间怎么确定?
根据 Play Console 文档:
当应用程序的第一帧完全加载时,将跟踪启动时间。
从 App 冷启动时间文档中了解到更多信息:
一旦婚恋系统源码的应用进程完成了第一次绘制,系统进程就会换出当前显示的背景窗口,用主 Activity 替换它。 此时,用户可以开始使用该应用程序。
ActivityThread.handleResumeActivity() 调度第一帧。
在第一帧 Choreographer.doFrame() 调用 ViewRootImpl.doTraversal() 执行测量传递、布局传递,最后是视图层次结构上的第一个绘制传递。
从 API 级别 16 开始,Android 提供了一个简单的 API 来安排婚恋系统源码下一帧发生时的回调:Choreographer.postFrameCallback()。
不幸的是,调用 Choreographer.postFrameCallback() 具有调度第一次遍历之前运行的帧的副作用。 所以这里报告的时间是在运行第一次绘制的帧的时间之前。 我能够在 API 25 上重现这个,但也注意到它不会在 API 30 中发生,所以这个错误可能已经修复。
在 Android 上,每个视图层次结构都有一个 ViewTreeObserver,它可以保存婚恋系统源码全局事件的回调,例如布局或绘制。
ViewTreeObserver.addOnDrawListener()
我们可以调用 ViewTreeObserver.addOnDrawListener() 来注册一个绘制监听器:
ViewTreeObserver.removeOnDrawListener()
我们只关心第一次绘制,因此我们需要在收到回调后立即删除 OnDrawListener。 不幸的是,无法从 onDraw() 回调中调用 ViewTreeObserver.removeOnDrawListener():
所以我们必须在一个 post 中进行删除:
注意扩展函数:
如果我们在婚恋系统源码附加视图层次结构之前调用 View.getViewTreeObserver() ,则没有真正的 ViewTreeObserver 可用,因此视图将创建一个假的来存储回调:
然后当视图被附加时,回调被合并回真正的 ViewTreeObserver。
除了在 API 26 中修复了一个错误:绘制侦听器没有合并回真实的视图树观察器。
我们通过在注册我们的绘制侦听器之前等待婚恋系统源码视图被附加来解决这个问题:
现在我们有一个很好的实用程序来监听下一次绘制,我们可以在创建 Activity 时使用它。 请注意,第一个创建的 Activity 可能不会绘制:应用程序将蹦床 Activity 作为启动器 Activity 是很常见的,它会立即启动另一个 Activity 并自行完成。 我们在 Activity 窗口 DecorView 上注册我们的绘制侦听器。
根据 Window.getDecorView() 的文档:
请注意,如 setContentView() 中所述,首次调用此函数会“锁定”各种窗口特征。
不幸的是,我们正在从 ActivityLifecycleCallbacks.onActivityCreated() 调用 Window.getDecorView(),它被 Activity.onCreate() 调用。 在一个典型的 Activity 中,setContentView() 在 super.onCreate() 之后被调用,所以我们在 setContentView() 被调用之前调用 Window.getDecorView(),这会产生意想不到的副作用。
在我们检索装饰视图之前,我们需要等待 setContentView() 被调用。
我们可以使用 Window.peekDecorView() 来确定我们是否已经有一个装饰视图。 如果没有,我们可以在我们的窗口上注册一个回调,它提供了我们需要的钩子,Window.Callback.onContentChanged():
只要屏幕的内容视图发生变化(由于调用 Window#setContentView() 或 Window#addContentView()),就会调用此钩子。
但是,一个窗口只能有一个回调,并且 Activity 已经将自己设置为窗口回调。 所以我们需要替换那个回调并委托给它。
这是一个实用程序类,它执行此操作并添加一个 Window.onDecorViewReady() 扩展函数:
让我们看看 OnDrawListener.onDraw() 文档:
即将绘制视图树时调用的回调方法。
婚恋系统源码绘图仍然需要一段时间。 我们想知道绘图何时完成,而不是何时开始。 不幸的是,没有 ViewTreeObserver.OnPostDrawListener API。
第一帧和遍历都发生在一个 MSG_DO_FRAME 消息中。 如果我们可以确定该消息何时结束,我们就会知道何时完成绘制。
与其确定 MSG_DO_FRAME 消息何时结束,我们可以通过使用 Handler.postAtFrontOfQueue() 发布到消息队列的前面来检测婚恋系统源码下一条消息何时开始:
编辑:我在婚恋系统源码上测量了生产中的第一个 onNextDraw() 和以下 postAtFrontOfQueue() 之间的时间差,以下是结果:
第 10 个百分位数:25ms
第 25 个百分位数:37 毫秒
第 50 个百分位数:61 毫秒
第 75 个百分位数:109 毫秒
第 90 个百分位数:194 毫秒
声明:本文由云豹科技转发自猫尾巴博客,如有侵权请联系作者删除
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70002045/viewspace-2838403/ ,如需转载,请注明出处,否则将追究法律责任。