背景前面文章有对冷启动的Splash Window进行了详细的但是大家是否有想过稳启动时候的是否也需要有类似的Splash Window呢答案是肯定的具体可以通过WinScope或者Perfetto抓取暖启动的过程来验证其实桌面的暖启动也会有一个StartingWindow名字叫做SnapshotStartingWindow他的启动时间明显比冷启动SplashWindow要快很多几乎为SplashWindow时间的1/2可以看到点击后SnapshotStartingWindow在68ms后就进行了上帧。再看看冷启动的SplashWindow的时间可以看出桌面点击后要118ms才有Splash window的绘制帧数据。SnapshotStartingWindow数据是啥冷启动时候大家都知道SplashWindow数据就是ICON 背景色的样子但是暖启动时候SnapshotStartingWindow显示内容是啥呢实际上他显示内容就是类似最近任务一样的是activity内容的截图获取方式截图文件保存在/data/system_ce/userId/snapshots/随机UUID/taskId.jpg /data/system_ce/userId/snapshots/随机UUID/taskId.proto /data/system_ce/userId/snapshots/随机UUID/taskId_reduced.jpg实战如下adb pull /data/system_ce/0/snapshots/09c8fa2d-ff1b-482f-882c-eb1e0b5ca51d/789.jpg /data/system_ce/0/snapshots/09c8fa2d-ff1b-482f-882c-eb1e0b5ca51d/789.jpg:1filepulled,0skipped.19.7MB/s(86913bytesin0.004s)为什么感知不到SnapshotStartingWindow存在呢其实感知不到SnapshotStartingWindow存在就是系统设计这个SnapshotStartingWindow成功的表现本身就是想让你无感的点击图标后进入到Activity真实内容但是因为Activity真实内容显示是需要一定时间的哪怕暖启动。那么在真实Activity绘制前这段时间就需要使用SnapshotStartingWindow来显示他显示的内容是上一次Activity退出的task截图。感知不到SnapshotStartingWindow存在其实有2个因素1、SnapshotStartingWindow的显示时间非常短暂可能是100ms左右相比SplashWindow显示500ms时间短了很多。2、SnapshotStartingWindow本身就是显示task的截图所以内容上和Activity的真实显示内容是高度一致的所以很难感知出他们的变化除非画面会有大的变化才可能会有跳变感。整体流程架构总结system_server (ATMS/WMS) Shell (com.android.wm.shell) ══════════════════════════ ═══════════════════════════════ ActivityRecord.addStartingWindow() │ ├─ getStartingWindowType() │ │ │ ├─ newTask/!processRunning → SPLASH │ └─ taskSwitch snapshot → SNAPSHOT ← 温启动命中 │ ├─ createSnapshot() │ └─ new SnapshotStartingData(snapshot) │ ├─ StartingSurfaceController │ .createTaskSnapshotSurface() │ └─ TaskOrganizerController .addStartingWindow() ──Binder IPC──▶ TaskSnapshotWindow.create() │ ├─ IWindowSession.addToDisplay() ├─ IWindowSession.relayout() ├─ SnapshotDrawerUtils │ .drawSnapshotOnSurface() │ └─ setBuffer(HardwareBuffer) └─ reportDrawn() ═══════ Snapshot 显示中App 首帧正在绘制 ═══════ ActivityRecord.onFirstWindowDrawn() │ └─ removeStartingWindow() │ └─ TaskOrganizerController .removeStartingWindow() ──Binder IPC──▶ TaskSnapshotWindow .removeImmediately() └─ IWindowSession.remove()添加路径:ActivityRecord→StartingSurfaceController→TaskOrganizerController→ Binder →TaskSnapshotWindow移除路径:ActivityRecord.onFirstWindowDrawn()→TaskOrganizerController→ Binder →TaskSnapshotWindow.removeImmediately()原文地址https://mp.weixin.qq.com/s/mtcG-00_KS-NyVs4bL5zEw更多fw实战干货请关注下面“千里马学框架”