Android T 远程动画显示流程其一——整体流程以及堆栈介绍

本地动画和远程动画区别是什么? 本地动画:自给自足。对自身SurfaceControl矢量动画进行控制。 远程动画:拿来吧你!一个app A对另一个app B通过binder跨进程通信,控制app B的SurfaceControl矢量动画。 无论是本地动画还是远程动画,都仅仅只是对SurfaceControl动画图层控制,而无法控制应用内部的View。 注:矢量动画包含位移、放大、缩小、透明度、圆角等。

常见的远程动画,就是桌面与应用交互。比如,我们从桌面点击一个应用启动这个应用,这个过程中会产生的动画就是远程动画。 我们从这个角度分析其动画显示过程。

整体流程

整体流程图

在桌面生命周期走到了onPause,应用生命周期走到了onResume时,窗口的绘制流程开始,窗口的relayout流程中开始远程动画。 WMS端会创建动画,然后通过跨进程通信,把动画图层和动画结束时的回调传递给桌面,桌面才是真正执行远程动画的的地方;当动画播放结束时,再次通过跨进程通信,让WMS端处理移除动画图层等扫尾工作(这个扫尾工作与本地动画结束时的流程相同)。

从流程上我们看,远程动画和本地动画区别在于: 我们可以理解为,远程动画就是桌面把启动的应用的动画拿到本地来播放。 相对于本地动画,远程动画只是多了两步通过跨进程通信,来拿到其他应用动画图层和通知WMS扫尾工作的过程。

图层分析

通过使用winscope抓取动态图层信息。我们这里以从桌面点开微信为例 这里我们暂时不关注壁纸的动画,我们可以发现应用的过渡动画图层是在DefaultTaskDsiplayArea和应用Task之间生成的,动画类型为app_transition。

从层级结构的角度来讲,远程动画和本地动画区别在于: 在层级结构树中的叶子节点与应用Task之间产生的动画图层属于远程动画;而在WindowState的容器(WindowToken或者ActivityRecord)与WindowState本身之间产生的动画图层为本地动画。 远程动画层级结构变化过程简图,如图所示:

显示过程分析

log添加

我们前面通过学习Android T 窗口动画(本地动画)显示流程,发现无论什么类型动画都有其创建和移除的过程,在SurfaceAnimator中createAnimationLeash和removeLeash添加log打印堆栈信息。 createAnimationLeash 添加log Slog.i("WindowManager","createAnimationLeash type = " + animationTypeToString(type) + " animatable = "+animatable, new Exception());

removeLeash 添加log Slog.i("WindowManager","removeLeash leash = " + leash , new Exception());

我们看看下面几种启动的动画创建和移除的过程(排除了insets类型的动画)

创建移除流程

冷启动

less 复制代码
WindowManager: createAnimationLeash type = app_transition animatable = Task{d0b86 #77 type=standard A=10116:com.example.mysystemdialog}
WindowManager: createAnimationLeash type = app_transition animatable = Task{2c8eb49 #1 type=home}
WindowManager: createAnimationLeash type = window_animation animatable = WallpaperWindowToken{79ea104 token=android.os.Binder@30f6996}
WindowManager: removeLeash leash = Surface(name=Surface(name=Task=1)/@0x50de32e - animation-leash of app_transition)/@0x5e2271f
WindowManager: removeLeash leash = Surface(name=Surface(name=Task=77)/@0xeb831c3 - animation-leash of app_transition)/@0xebdcd79
WindowManager: removeLeash leash = Surface(name=Surface(name=WallpaperWindowToken{79ea104 token=android.os.Binder@30f6996})/@0xa32d428 - animation-leash of window_animation)/@0xd323396
WindowManager: createAnimationLeash type = starting_reveal animatable = Window{a65f40b u0 com.example.mysystemdialog/com.example.mysystemdialog.MainActivity}
WindowManager: createAnimationLeash type = window_animation animatable = Window{dad6bc2 u0 Splash Screen com.example.mysystemdialog}
WindowManager: removeLeash leash = Surface(name=Surface(name=a65f40b com.example.mysystemdialog/com.example.mysystemdialog.MainActivity)/@0xdbce2c1 - animation-leash of starting_reveal)/@0x6df31a7
WindowManager: removeLeash leash = Surface(name=Surface(name=dad6bc2 Splash Screen com.example.mysystemdialog)/@0x3868f87 - animation-leash of window_animation)/@0x9d22add

应用不在后台运行,从桌面点击一个应用冷启动,动画顺序如下:

动画窗口 动画类型 操作
mysystemdialog(Task) app_transition 创建
home(桌面Task) app_transition 创建
WallpaperWindowToken(壁纸) window_animation 创建
home(桌面Task) app_transition 移除
mysystemdialog(Task) app_transition 移除
WallpaperWindowToken(壁纸) app_transition 移除
MainActivity冷启动应用主界面(ActivityRecord) starting_reveal 创建
mysystemdialog的冷启动窗口(Splash Screen) window_animation 创建
MainActivity冷启动应用主界面(ActivityRecord) starting_reveal 移除
mysystemdialog的冷启动窗口(Splash Screen) window_animation 移除

热启动

less 复制代码
WindowManager: createAnimationLeash type = app_transition animatable = Task{d0b86 #77 type=standard A=10116:com.example.mysystemdialog}
WindowManager: createAnimationLeash type = app_transition animatable = Task{2c8eb49 #1 type=home}
WindowManager: createAnimationLeash type = window_animation animatable = WallpaperWindowToken{79ea104 token=android.os.Binder@30f6996}
WindowManager: removeLeash leash = Surface(name=Surface(name=Task=1)/@0x50de32e - animation-leash of app_transition)/@0x6c5dc4f
WindowManager: removeLeash leash = Surface(name=Surface(name=Task=77)/@0xeb831c3 - animation-leash of app_transition)/@0x8775329
WindowManager: removeLeash leash = Surface(name=Surface(name=WallpaperWindowToken{79ea104 token=android.os.Binder@30f6996})/@0xa32d428 - animation-leash of window_animation)/@0x8534d86
WindowManager: createAnimationLeash type = window_animation animatable = Window{d22fcb2 u0 SnapshotStartingWindow for taskId=77}
WindowManager: removeLeash leash = Surface(name=Surface(name=d22fcb2 SnapshotStartingWindow for taskId=77)/@0xfcbebd0 - animation-leash of window_animation)/@0x3faeece

应用本身就在后台运行,从桌面热启动应用,动画顺序如下:

动画窗口 动画类型 操作
mysystemdialog(Task) app_transition 创建
home(桌面Task) app_transition 创建
WallpaperWindowToken(壁纸) window_animation 创建
home(桌面Task) app_transition 移除
mysystemdialog(Task) app_transition 移除
WallpaperWindowToken(壁纸) app_transition 移除
mysystemdialog的热启动窗口(SnapshotStartingWindow) window_animation 创建
mysystemdialog的热启动窗口(SnapshotStartingWindow) window_animation 移除

home回到桌面

less 复制代码
WindowManager: createAnimationLeash type = app_transition animatable = Task{2c8eb49 #1 type=home}
WindowManager: createAnimationLeash type = app_transition animatable = Task{d0b86 #77 type=standard A=10116:com.example.mysystemdialog}
WindowManager: createAnimationLeash type = window_animation animatable = WallpaperWindowToken{79ea104 token=android.os.Binder@30f6996}
WindowManager: removeLeash leash = Surface(name=Surface(name=Task=77)/@0xeb831c3 - animation-leash of app_transition)/@0x77da703
WindowManager: removeLeash leash = Surface(name=Surface(name=Task=1)/@0x50de32e - animation-leash of app_transition)/@0x12ce9bd
WindowManager: removeLeash leash = Surface(name=Surface(name=WallpaperWindowToken{79ea104 token=android.os.Binder@30f6996})/@0xa32d428 - animation-leash of window_animation)/@0x5e69f0a

在应用界面,点击home键退回到桌面界面,动画顺序如下:

动画窗口 动画类型 操作
home(桌面Task) app_transition 创建
mysystemdialog(Task) app_transition 创建
WallpaperWindowToken(壁纸) window_animation 创建
mysystemdialog(Task) app_transition 移除
home(桌面Task) app_transition 移除
WallpaperWindowToken(壁纸) window_animation 移除

关键堆栈

创建动画图层 createAnimationLeash

桌面

java 复制代码
WindowManager: createAnimationLeash type = app_transition animatable = Task{2c8eb49 #1 type=home}
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.createAnimationLeash(SurfaceAnimator.java:472)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:186)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2810)
WindowManager: 	at com.android.server.wm.WindowContainer$AnimationRunnerBuilder.lambda$build$4(WindowContainer.java:4078)
WindowManager: 	at com.android.server.wm.WindowContainer$AnimationRunnerBuilder.$r8$lambda$BWeVZQp29j72z9D_sWdID2xR4qI(Unknown Source:0)
WindowManager: 	at com.android.server.wm.WindowContainer$AnimationRunnerBuilder$$ExternalSyntheticLambda1.startAnimation(Unknown Source:7)
WindowManager: 	at com.android.server.wm.WindowContainer.applyAnimationUnchecked(WindowContainer.java:3174)
WindowManager: 	at com.android.server.wm.Task.applyAnimationUnchecked(Task.java:3366)
WindowManager: 	at com.android.server.wm.WindowContainer.applyAnimation(WindowContainer.java:2958)
WindowManager: 	at com.android.server.wm.AppTransitionController.applyAnimations(AppTransitionController.java:882)
WindowManager: 	at com.android.server.wm.AppTransitionController.applyAnimations(AppTransitionController.java:1085)
WindowManager: 	at com.android.server.wm.AppTransitionController.handleAppTransitionReady(AppTransitionController.java:266)
WindowManager: 	at com.android.server.wm.RootWindowContainer.checkAppTransitionReady(RootWindowContainer.java:970)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:834)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:777)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:57)
WindowManager: 	at android.os.Handler.handleCallback(Handler.java:942)
WindowManager: 	at android.os.Handler.dispatchMessage(Handler.java:99)
WindowManager: 	at android.os.Looper.loopOnce(Looper.java:201)
WindowManager: 	at android.os.Looper.loop(Looper.java:288)
WindowManager: 	at android.os.HandlerThread.run(HandlerThread.java:67)
WindowManager: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

应用task

java 复制代码
WindowManager: createAnimationLeash type = app_transition animatable = Task{d0b86 #77 type=standard A=10116:com.example.mysystemdialog}
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.createAnimationLeash(SurfaceAnimator.java:472)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:186)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2810)
WindowManager: 	at com.android.server.wm.WindowContainer$AnimationRunnerBuilder.lambda$build$4(WindowContainer.java:4078)
WindowManager: 	at com.android.server.wm.WindowContainer$AnimationRunnerBuilder.$r8$lambda$BWeVZQp29j72z9D_sWdID2xR4qI(Unknown Source:0)
WindowManager: 	at com.android.server.wm.WindowContainer$AnimationRunnerBuilder$$ExternalSyntheticLambda1.startAnimation(Unknown Source:7)
WindowManager: 	at com.android.server.wm.WindowContainer.applyAnimationUnchecked(WindowContainer.java:3174)
WindowManager: 	at com.android.server.wm.Task.applyAnimationUnchecked(Task.java:3366)
WindowManager: 	at com.android.server.wm.WindowContainer.applyAnimation(WindowContainer.java:2958)
WindowManager: 	at com.android.server.wm.AppTransitionController.applyAnimations(AppTransitionController.java:882)
WindowManager: 	at com.android.server.wm.AppTransitionController.applyAnimations(AppTransitionController.java:1087)
WindowManager: 	at com.android.server.wm.AppTransitionController.handleAppTransitionReady(AppTransitionController.java:266)
WindowManager: 	at com.android.server.wm.RootWindowContainer.checkAppTransitionReady(RootWindowContainer.java:970)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:834)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:777)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:57)
WindowManager: 	at android.os.Handler.handleCallback(Handler.java:942)
WindowManager: 	at android.os.Handler.dispatchMessage(Handler.java:99)
WindowManager: 	at android.os.Looper.loopOnce(Looper.java:201)
WindowManager: 	at android.os.Looper.loop(Looper.java:288)
WindowManager: 	at android.os.HandlerThread.run(HandlerThread.java:67)
WindowManager: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

壁纸

java 复制代码
WindowManager: createAnimationLeash type = window_animation animatable = WallpaperWindowToken{79ea104 token=android.os.Binder@30f6996}
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.createAnimationLeash(SurfaceAnimator.java:472)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:186)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2810)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2817)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2823)
WindowManager: 	at com.android.server.wm.WallpaperAnimationAdapter.lambda$startWallpaperAnimations$0(WallpaperAnimationAdapter.java:82)
WindowManager: 	at com.android.server.wm.WallpaperAnimationAdapter.$r8$lambda$pFt1sM34mQb-FFZsZckZ6IVTj_M(Unknown Source:0)
WindowManager: 	at com.android.server.wm.WallpaperAnimationAdapter$$ExternalSyntheticLambda0.accept(Unknown Source:13)
WindowManager: 	at com.android.server.wm.WallpaperWindowToken.forAllWallpaperWindows(WallpaperWindowToken.java:214)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWallpaperWindows(WindowContainer.java:1911)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWallpaperWindows(WindowContainer.java:1911)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWallpaperWindows(WindowContainer.java:1911)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWallpaperWindows(WindowContainer.java:1911)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWallpaperWindows(WindowContainer.java:1911)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWallpaperWindows(WindowContainer.java:1911)
WindowManager: 	at com.android.server.wm.WallpaperAnimationAdapter.startWallpaperAnimations(WallpaperAnimationAdapter.java:78)
WindowManager: 	at com.android.server.wm.RemoteAnimationController.createWallpaperAnimations(RemoteAnimationController.java:270)
WindowManager: 	at com.android.server.wm.RemoteAnimationController.goodToGo(RemoteAnimationController.java:185)
WindowManager: 	at com.android.server.wm.AppTransition.goodToGo(AppTransition.java:419)
WindowManager: 	at com.android.server.wm.AppTransitionController.handleAppTransitionReady(AppTransitionController.java:277)
WindowManager: 	at com.android.server.wm.RootWindowContainer.checkAppTransitionReady(RootWindowContainer.java:970)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:834)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:777)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:57)
WindowManager: 	at android.os.Handler.handleCallback(Handler.java:942)
WindowManager: 	at android.os.Handler.dispatchMessage(Handler.java:99)
WindowManager: 	at android.os.Looper.loopOnce(Looper.java:201)
WindowManager: 	at android.os.Looper.loop(Looper.java:288)
WindowManager: 	at android.os.HandlerThread.run(HandlerThread.java:67)
WindowManager: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

starting_reveal

java 复制代码
WindowManager: createAnimationLeash type = starting_reveal animatable = Window{f64bf2d u0 com.example.mysystemdialog/com.example.mysystemdialog.MainActivity}
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.createAnimationLeash(SurfaceAnimator.java:472)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:186)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2810)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2817)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2823)
WindowManager: 	at com.android.server.wm.TaskOrganizerController.applyStartingWindowAnimation(TaskOrganizerController.java:634)
WindowManager: 	at com.android.server.wm.TaskOrganizerController.removeStartingWindow(TaskOrganizerController.java:696)
WindowManager: 	at com.android.server.wm.StartingSurfaceController$StartingSurface.remove(StartingSurfaceController.java:271)
WindowManager: 	at com.android.server.wm.ActivityRecord.lambda$removeStartingWindowAnimation$4(ActivityRecord.java:2787)
WindowManager: 	at com.android.server.wm.ActivityRecord.$r8$lambda$cZFIJhaFFrS84y2PDOOXTP_CRFs(Unknown Source:0)
WindowManager: 	at com.android.server.wm.ActivityRecord$$ExternalSyntheticLambda16.run(Unknown Source:4)
WindowManager: 	at com.android.server.wm.ActivityRecord.removeStartingWindowAnimation(ActivityRecord.java:2803)
WindowManager: 	at com.android.server.wm.ActivityRecord.removeStartingWindow(ActivityRecord.java:2732)
WindowManager: 	at com.android.server.wm.ActivityRecord.onFirstWindowDrawn(ActivityRecord.java:6577)
WindowManager: 	at com.android.server.wm.WindowState.performShowLocked(WindowState.java:4674)
WindowManager: 	at com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked(WindowStateAnimator.java:274)
WindowManager: 	at com.android.server.wm.DisplayContent.lambda$new$8(DisplayContent.java:1099)
WindowManager: 	at com.android.server.wm.DisplayContent.$r8$lambda$OtLCIQFjCt9o-SYztyeDUcWUwGs(Unknown Source:0)
WindowManager: 	at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda10.accept(Unknown Source:4)
WindowManager: 	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2684)
WindowManager: 	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2674)
WindowManager: 	at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4942)
WindowManager: 	at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4786)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1672)
WindowManager: 	at com.android.server.wm.DisplayContent.applySurfaceChangesTransaction(DisplayContent.java:4946)
WindowManager: 	at com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction(RootWindowContainer.java:1014)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:816)
WindowManager: 	at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:777)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
WindowManager: 	at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:57)
WindowManager: 	at android.os.Handler.handleCallback(Handler.java:942)
WindowManager: 	at android.os.Handler.dispatchMessage(Handler.java:99)
WindowManager: 	at android.os.Looper.loopOnce(Looper.java:201)
WindowManager: 	at android.os.Looper.loop(Looper.java:288)
WindowManager: 	at android.os.HandlerThread.run(HandlerThread.java:67)
WindowManager: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

冷启动窗口

java 复制代码
WindowManager: createAnimationLeash type = window_animation animatable = Window{4d28c0 u0 Splash Screen com.example.mysystemdialog}
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.createAnimationLeash(SurfaceAnimator.java:472)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:186)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2810)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2817)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2823)
WindowManager: 	at com.android.server.wm.WindowState.startAnimation(WindowState.java:5327)
WindowManager: 	at com.android.server.wm.WindowState.startAnimation(WindowState.java:5303)
WindowManager: 	at com.android.server.wm.WindowStateAnimator.applyAnimationLocked(WindowStateAnimator.java:652)
WindowManager: 	at com.android.server.wm.WindowManagerService.tryStartExitingAnimation(WindowManagerService.java:2642)
WindowManager: 	at com.android.server.wm.WindowManagerService.relayoutWindow(WindowManagerService.java:2448)
WindowManager: 	at com.android.server.wm.Session.relayout(Session.java:253)
WindowManager: 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:727)
WindowManager: 	at com.android.server.wm.Session.onTransact(Session.java:178)
WindowManager: 	at android.os.Binder.execTransactInternal(Binder.java:1285)
WindowManager: 	at android.os.Binder.execTransact(Binder.java:1244)

热启动窗口

java 复制代码
WindowManager: createAnimationLeash type = window_animation animatable = Window{d22fcb2 u0 SnapshotStartingWindow for taskId=77}
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.createAnimationLeash(SurfaceAnimator.java:472)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:186)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2810)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2817)
WindowManager: 	at com.android.server.wm.WindowContainer.startAnimation(WindowContainer.java:2823)
WindowManager: 	at com.android.server.wm.WindowState.startAnimation(WindowState.java:5327)
WindowManager: 	at com.android.server.wm.WindowState.startAnimation(WindowState.java:5303)
WindowManager: 	at com.android.server.wm.WindowStateAnimator.applyAnimationLocked(WindowStateAnimator.java:652)
WindowManager: 	at com.android.server.wm.WindowState.removeIfPossible(WindowState.java:2593)
WindowManager: 	at com.android.server.wm.WindowState.removeIfPossible(WindowState.java:2487)
WindowManager: 	at com.android.server.wm.WindowManagerService.removeWindow(WindowManagerService.java:2053)
WindowManager: 	at com.android.server.wm.Session.remove(Session.java:230)
WindowManager: 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:687)
WindowManager: 	at com.android.server.wm.Session.onTransact(Session.java:178)
WindowManager: 	at android.os.Binder.execTransactInternal(Binder.java:1285)
WindowManager: 	at android.os.Binder.execTransact(Binder.java:1244)

移除动画图层 removeLeash

桌面

java 复制代码
0WindowManager: removeLeash leash = Surface(name=Surface(name=Task=1)/@0x50de32e - animation-leash of app_transition)/@0x12ce9bd
0WindowManager: java.lang.Exception
0WindowManager: 	at com.android.server.wm.SurfaceAnimator.removeLeash(SurfaceAnimator.java:423)
0WindowManager: 	at com.android.server.wm.SurfaceAnimator.reset(SurfaceAnimator.java:413)
0WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$0(SurfaceAnimator.java:132)
0WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$lRxTVOJy8fX752UbrFno9INW9hE(Unknown Source:0)
0WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda1.run(Unknown Source:8)
0WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$1(SurfaceAnimator.java:144)
0WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$4PiCdaEsT4mA6LQVhqpeM5EoU9c(Unknown Source:0)
0WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda0.onAnimationFinished(Unknown Source:4)
0WindowManager: 	at com.android.server.wm.RemoteAnimationController.onAnimationFinished(RemoteAnimationController.java:307)
0WindowManager: 	at com.android.server.wm.RemoteAnimationController.-$$Nest$monAnimationFinished(Unknown Source:0)
0WindowManager: 	at com.android.server.wm.RemoteAnimationController$FinishedCallback.onAnimationFinished(RemoteAnimationController.java:418)
0WindowManager: 	at android.view.IRemoteAnimationFinishedCallback$Stub.onTransact(IRemoteAnimationFinishedCallback.java:89)
0WindowManager: 	at android.os.Binder.execTransactInternal(Binder.java:1285)
0WindowManager: 	at android.os.Binder.execTransact(Binder.java:1244)

应用task

java 复制代码
WindowManager: removeLeash leash = Surface(name=Surface(name=Task=77)/@0xeb831c3 - animation-leash of app_transition)/@0x77da703
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.removeLeash(SurfaceAnimator.java:423)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.reset(SurfaceAnimator.java:413)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$0(SurfaceAnimator.java:132)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$lRxTVOJy8fX752UbrFno9INW9hE(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda1.run(Unknown Source:8)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$1(SurfaceAnimator.java:144)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$4PiCdaEsT4mA6LQVhqpeM5EoU9c(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda0.onAnimationFinished(Unknown Source:4)
WindowManager: 	at com.android.server.wm.RemoteAnimationController.onAnimationFinished(RemoteAnimationController.java:307)
WindowManager: 	at com.android.server.wm.RemoteAnimationController.-$$Nest$monAnimationFinished(Unknown Source:0)
WindowManager: 	at com.android.server.wm.RemoteAnimationController$FinishedCallback.onAnimationFinished(RemoteAnimationController.java:418)
WindowManager: 	at android.view.IRemoteAnimationFinishedCallback$Stub.onTransact(IRemoteAnimationFinishedCallback.java:89)
WindowManager: 	at android.os.Binder.execTransactInternal(Binder.java:1285)
WindowManager: 	at android.os.Binder.execTransact(Binder.java:1244)

壁纸

java 复制代码
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.removeLeash(SurfaceAnimator.java:423)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.reset(SurfaceAnimator.java:413)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$0(SurfaceAnimator.java:132)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$lRxTVOJy8fX752UbrFno9INW9hE(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda1.run(Unknown Source:8)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$1(SurfaceAnimator.java:144)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$4PiCdaEsT4mA6LQVhqpeM5EoU9c(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda0.onAnimationFinished(Unknown Source:4)
WindowManager: 	at com.android.server.wm.RemoteAnimationController.onAnimationFinished(RemoteAnimationController.java:322)
WindowManager: 	at com.android.server.wm.RemoteAnimationController.-$$Nest$monAnimationFinished(Unknown Source:0)
WindowManager: 	at com.android.server.wm.RemoteAnimationController$FinishedCallback.onAnimationFinished(RemoteAnimationController.java:418)
WindowManager: 	at android.view.IRemoteAnimationFinishedCallback$Stub.onTransact(IRemoteAnimationFinishedCallback.java:89)
WindowManager: 	at android.os.Binder.execTransactInternal(Binder.java:1285)
WindowManager: 	at android.os.Binder.execTransact(Binder.java:1244)

starting_reveal

java 复制代码
WindowManager: removeLeash leash = Surface(name=Surface(name=f64bf2d com.example.mysystemdialog/com.example.mysystemdialog.MainActivity)/@0xdf5580d - animation-leash of starting_reveal)/@0x6af05d3
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.removeLeash(SurfaceAnimator.java:423)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.reset(SurfaceAnimator.java:413)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.cancelAnimation(SurfaceAnimator.java:364)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.cancelAnimation(SurfaceAnimator.java:270)
WindowManager: 	at com.android.server.wm.WindowContainer.cancelAnimation(WindowContainer.java:2832)
WindowManager: 	at com.android.server.wm.WindowState.lambda$removeIfPossible$2(WindowState.java:2503)
WindowManager: 	at com.android.server.wm.WindowState.$r8$lambda$gtdPXCAzSiavwVZY5OZGcTDMs84(Unknown Source:0)
WindowManager: 	at com.android.server.wm.WindowState$$ExternalSyntheticLambda0.apply(Unknown Source:2)
WindowManager: 	at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4942)
WindowManager: 	at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4786)
WindowManager: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1655)
WindowManager: 	at com.android.server.wm.WindowState.removeIfPossible(WindowState.java:2501)
WindowManager: 	at com.android.server.wm.WindowState.removeIfPossible(WindowState.java:2487)
WindowManager: 	at com.android.server.wm.WindowManagerService.removeWindow(WindowManagerService.java:2053)
WindowManager: 	at com.android.server.wm.Session.remove(Session.java:230)
WindowManager: 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:687)
WindowManager: 	at com.android.server.wm.Session.onTransact(Session.java:178)
WindowManager: 	at android.os.Binder.execTransactInternal(Binder.java:1285)
WindowManager: 	at android.os.Binder.execTransact(Binder.java:1244)

冷启动窗口

java 复制代码
WindowManager: removeLeash leash = Surface(name=Surface(name=4d28c0 Splash Screen com.example.mysystemdialog)/@0xbbbe9b3 - animation-leash of window_animation)/@0x7ca9ee9
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.removeLeash(SurfaceAnimator.java:423)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.reset(SurfaceAnimator.java:413)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$0(SurfaceAnimator.java:132)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$lRxTVOJy8fX752UbrFno9INW9hE(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda1.run(Unknown Source:8)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$1(SurfaceAnimator.java:144)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$4PiCdaEsT4mA6LQVhqpeM5EoU9c(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda0.onAnimationFinished(Unknown Source:4)
WindowManager: 	at com.android.server.wm.LocalAnimationAdapter.lambda$startAnimation$0(LocalAnimationAdapter.java:67)
WindowManager: 	at com.android.server.wm.LocalAnimationAdapter.$r8$lambda$gPDCFw0mQLltlXqA3mL6IUKCwLs(Unknown Source:0)
WindowManager: 	at com.android.server.wm.LocalAnimationAdapter$$ExternalSyntheticLambda0.run(Unknown Source:6)
WindowManager: 	at android.os.Handler.handleCallback(Handler.java:942)
WindowManager: 	at android.os.Handler.dispatchMessage(Handler.java:99)
WindowManager: 	at android.os.Looper.loopOnce(Looper.java:201)
WindowManager: 	at android.os.Looper.loop(Looper.java:288)
WindowManager: 	at android.os.HandlerThread.run(HandlerThread.java:67)
WindowManager: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

热启动窗口

java 复制代码
WindowManager: removeLeash leash = Surface(name=Surface(name=d22fcb2 SnapshotStartingWindow for taskId=77)/@0xfcbebd0 - animation-leash of window_animation)/@0x3faeece
WindowManager: java.lang.Exception
WindowManager: 	at com.android.server.wm.SurfaceAnimator.removeLeash(SurfaceAnimator.java:423)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.reset(SurfaceAnimator.java:413)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$0(SurfaceAnimator.java:132)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$lRxTVOJy8fX752UbrFno9INW9hE(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda1.run(Unknown Source:8)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$1(SurfaceAnimator.java:144)
WindowManager: 	at com.android.server.wm.SurfaceAnimator.$r8$lambda$4PiCdaEsT4mA6LQVhqpeM5EoU9c(Unknown Source:0)
WindowManager: 	at com.android.server.wm.SurfaceAnimator$$ExternalSyntheticLambda0.onAnimationFinished(Unknown Source:4)
WindowManager: 	at com.android.server.wm.LocalAnimationAdapter.lambda$startAnimation$0(LocalAnimationAdapter.java:67)
WindowManager: 	at com.android.server.wm.LocalAnimationAdapter.$r8$lambda$gPDCFw0mQLltlXqA3mL6IUKCwLs(Unknown Source:0)
WindowManager: 	at com.android.server.wm.LocalAnimationAdapter$$ExternalSyntheticLambda0.run(Unknown Source:6)
WindowManager: 	at android.os.Handler.handleCallback(Handler.java:942)
WindowManager: 	at android.os.Handler.dispatchMessage(Handler.java:99)
WindowManager: 	at android.os.Looper.loopOnce(Looper.java:201)
WindowManager: 	at android.os.Looper.loop(Looper.java:288)
WindowManager: 	at android.os.HandlerThread.run(HandlerThread.java:67)
WindowManager: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

小结

从当前分析以及堆栈来看,应用的启动窗口相关动画(冷启动应用主界面starting_reveal、冷启动窗口Splash Screen、热启动窗口SnapshotStartingWindow)均为本地动画,其他的动画均为远程动画。

本地动画: 窗口类型:冷启动应用主界面starting_reveal、冷启动窗口Splash Screen、热启动窗口SnapshotStartingWindow。 代码逻辑:创建动画时,从applyAnimationLocked流程到createAnimationLeash;移除动画时,从LocalAnimationAdapter的Callback到removeLeash流程。 注:starting_reveal类型动画比较特殊,涉及到StartingWindow动画流程。 远程动画: 窗口类型:桌面Task、应用Task、壁纸。 代码逻辑:创建动画时,从handleAppTransitionReady流程到createAnimationLeash;移除动画时,从IRemoteAnimationFinishedCallback流程到removeLeash流程。

补充

RemoteAnimationAdapter的创建

代码路径:packages/apps/Launcher3/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java

java 复制代码
    /**
     * @return ActivityOptions with remote animations that controls how the window of the opening
     * targets are displayed.
     */
    public ActivityOptionsWrapper getActivityLaunchOptions(View v) {
        boolean fromRecents = isLaunchingFromRecents(v, null /* targets */);
        RunnableList onEndCallback = new RunnableList();
        //创建AppLaunchAnimationRunner
        mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback);
        //创建LauncherAnimationRunner
        RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(
                mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */);

        // Note that this duration is a guess as we do not know if the animation will be a
        // recents launch or not for sure until we know the opening app targets.
        long duration = fromRecents
                ? RECENTS_LAUNCH_DURATION
                : APP_LAUNCH_DURATION;

        long statusBarTransitionDelay = duration - STATUS_BAR_TRANSITION_DURATION
                - STATUS_BAR_TRANSITION_PRE_DELAY;
        ActivityOptions options = ActivityOptions.makeRemoteAnimation(
                new RemoteAnimationAdapter(runner, duration, statusBarTransitionDelay),
                new RemoteTransition(runner.toRemoteTransition(),
                        mLauncher.getIApplicationThread()));
        return new ActivityOptionsWrapper(options, onEndCallback);
    }

这个方法主要就是干了这三件事: 1.创建AppLaunchAnimationRunner,即LauncherAnimationRunner中RemoteAnimationFactory的实现 2.创建LauncherAnimationRunner,即桌面端IRemoteAnimationRunner的实现 3.ActivityOptions.makeRemoteAnimation传递IRemoteAnimationRunner对象,创建并设置RemoteAnimationAdapter

RemoteAnimationController的创建

代码路径:frameworks/base/services/core/java/com/android/server/wm/AppTransition.java

java 复制代码
    void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
        overridePendingAppTransitionRemote(remoteAnimationAdapter, false /* sync */,
                false /* isActivityEmbedding*/);
    }

    void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter,
                                            boolean sync, boolean isActivityEmbedding) {
        ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s",
                isTransitionSet(), remoteAnimationAdapter);
        if (isTransitionSet() && !mNextAppTransitionIsSync) {
            // ActivityEmbedding animation will run by the app process for which we want to respect
            // the app override for whether or not to show background color.
            clear(!isActivityEmbedding /* clearAppOverride */);
            mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
            mRemoteAnimationController = new RemoteAnimationController(mService, mDisplayContent,
                    remoteAnimationAdapter, mHandler, isActivityEmbedding);
            mNextAppTransitionIsSync = sync;
        }
    }

传递sync值为false,和isActivityEmbedding值为false,从而创建RemoteAnimationController

后续流程

系统侧动画启动流程

Android T 远程动画显示流程其二------系统侧动画启动流程

桌面侧动画启动到系统侧结束流程

Android T 远程动画显示流程其三------桌面侧动画启动到系统侧结束流程

相关推荐
小蜜蜂嗡嗡26 分钟前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0032 分钟前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
zhangphil2 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你2 小时前
Android View的绘制原理详解
android
移动开发者1号5 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号5 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best10 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk10 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭15 小时前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin
aqi0015 小时前
FFmpeg开发笔记(七十七)Android的开源音视频剪辑框架RxFFmpeg
android·ffmpeg·音视频·流媒体