背景
前面文章有对冷启动的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: 1 file pulled, 0 skipped. 19.7 MB/s (86913 bytes in 0.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实战干货请关注下面“千里马学框架”
1039



被折叠的 条评论
为什么被折叠?



