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

这篇具有很好参考价值的文章主要介绍了Android T 远程动画显示流程其一——整体流程以及堆栈介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

整体流程

整体流程图

attachthumbnailanimation,Android Framework从入门到入土,Android 窗口动画,Android 窗口相关,android

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

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

图层分析

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

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

显示过程分析

log添加

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

removeLeash
attachthumbnailanimation,Android Framework从入门到入土,Android 窗口动画,Android 窗口相关,android添加log
Slog.i("WindowManager","removeLeash leash = " + leash , new Exception());

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

创建移除流程

冷启动

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 移除

热启动

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回到桌面

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

桌面
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
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)
壁纸
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
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)
冷启动窗口
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)
热启动窗口
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

桌面
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
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)
壁纸
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
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)
冷启动窗口
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)
热启动窗口
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

    /**
     * @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

    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 远程动画显示流程其二文章来源地址https://www.toymoban.com/news/detail-848082.html

到了这里,关于Android T 远程动画显示流程其一——整体流程以及堆栈介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android小技巧:在通知RemoteViews中显示动画

    在Android Notification显示中,我们通常显示一些静态元素,即便使用自定义布局,也不例外,因为 RemoteViews 有着诸多限制,例如使用的控件只有那些个基本控件,更新界面也必须通过 RemoteViews 提供的各种set方法。但有时候,我们就是想要去显示动画,因为动画可以提供更好的视

    2024年02月13日
    浏览(26)
  • Android 画面显示流程三

    画面更新流程 从底层的显示硬件,SOC和DDIC的接口,linux和Userspace的图形接口以及APP与SurfaceFlinger,HWC service三者关系,了解了帧数据流动所经过的关键节点,并重点讨论了帧buffer是如何管理的,以及在流动过程中是如何做到同步的。接下来我们将从应用侧角度从山到下看一下应

    2024年02月13日
    浏览(65)
  • Android 画面显示流程二

    BufferQueue BufferQueue要解决的是生产者的同步问题,应用程序生产画面,SurfaceFlinger消费画面,SurfaceFlinger生产画面而HWCService消费画面。用来存储这些画面的存储区我们称其为帧缓冲区buffer,下面我们以应用程序作为生产者,SurfaceFlinger作为消费者为例来了解一下BufferQueue的内部设

    2024年02月13日
    浏览(47)
  • UE4学习笔记——解决动画重定向后整体位移消失问题

    我用到的动作资源是一个双手剑的动画集合,用到的是小白人标准骨骼(其实不标准,原作者添加了weapon骨骼即双手剑的系列骨骼,但是没什么影响),而我想要重定向的目标来自虚幻商城中的免费资源“虚幻争霸:锐斯”的改动版(①我将锐斯的模型导入Blender进行了修改,

    2024年02月03日
    浏览(44)
  • Android Studio基础工作流程-xml布局文件如何调用显示

    说起安卓开发,很多小伙伴在刚开始入门的时候会有些云里雾里,觉得很混乱,这很正常,大多数是因为不太清楚安卓开发的基本流程,以及各个文件之间是怎样去相互作用的。我会在这篇文章里面向你介绍一下Android studio工作的基本流程,很基础很基础的那种。 一个完整的

    2024年02月03日
    浏览(30)
  • stm32以及freertos 堆栈解析

    以前在mcu编程的时候没有太注意堆栈的情况,只知道需要将堆栈设置的大一点。现在逐步使用freertos,在freertos中也有关于堆栈的设置,freertos的堆栈和启动文件中的堆栈关系是什么?为了以后使用的无误,本次一次性把这些弄清楚。 堆栈是一个特定的存储区或者寄存器。一般

    2023年04月08日
    浏览(36)
  • 程序的各种段以及堆栈相关问题

    C中一般有三种变量: 局部变量 全局变量 静态变量 C中一般有五个内存段: 代码段 也叫文本段,包含frequently executed code 通常是只读的(未了避免程序被错误改写) 代码段是不包含程序变量(如局部变量、全局变量)的 代码段可以包含只读的string字符,如包含代码 printf(\\\"H

    2024年02月05日
    浏览(28)
  • Android后退堆栈

    现在的ItemClick使得用户单击其中一个项目时就会跳转,现在要修改其使得在一个小屏幕设备上才会这样做,在一个大屏幕设备上运行用户选择一个训练项目时在右边的片段显示响应的信息。 希望片段处理后退的方式:假设用户在手机上运行这个应用,单击一个训练项目时,会

    2024年02月10日
    浏览(29)
  • Android 12.0 系统systemui状态栏下拉左滑显示通知栏右滑显示控制中心模块的流程分析

      在android12.0的系统rom定制化开发中,在系统原生systemui进行自定义下拉状态栏布局的定制的时候,需要在systemui下拉状态栏下滑的时候,根据下滑坐标来 判断当前是滑出通知栏还是滑出控制中心模块,所以就需要根据屏幕宽度,来区分x坐标值为多少是左滑出通知栏或者右滑

    2024年02月09日
    浏览(45)
  • Android 10.0 系统systemui状态栏下拉左滑显示通知栏右滑显示控制中心模块的流程分析

      在android10.0的系统rom定制化开发中,在系统原生systemui进行自定义下拉状态栏布局的定制的时候,需要在systemui下拉状态栏下滑的时候,根据下滑坐标来 判断当前是滑出通知栏还是滑出控制中心模块,所以就需要根据屏幕宽度,来区分x坐标值为多少是左滑出通知栏或者右滑

    2023年04月09日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包