推广 热搜:   公司    快速  中国  企业  行业  设备  未来  上海 

旋转动画停顿一下 android 手机旋转动画旋转手机「旋转动画停顿一下 android 手机旋转动画」

   日期:2025-02-02     移动:http://keair.bhha.com.cn/mobile/quote/9292.html


触发流程,这里我先只考虑正常窗手机传感器检测到了有旋转然后触发横竖屏情况,为了方便这里需要对相关的PROTO日志打开:
具体如下:
adb shell wm logging enable-text WM_DEBUG_ORIENTATION WM_DEBUG_STATES WM_DEBUG_CONFIGURATION
最主要这里一定要WM_DEBUG_ORIENTATION,它就是专门来打印相关的旋转屏幕信息,开启屏幕自动旋转,然后进入一个会有旋转屏幕现象的Activity,旋转抓取日志:

这里面就其实已经有对应的一个堆栈打印了,都不需要我们额外再自己加什么堆栈日志,从最后的startFreezingDisplayLocked来看堆栈:
com.android.server.wm.WindowManagerService.startFreezingDisplay:6019 com.android.server.wm.DisplayRotation.prepareNormalRotationAnimation:619 com.android.server.wm.DisplayRotation.updateRotationUnchecked:536 com.android.server.wm.DisplayContent.updateRotationUnchecked:1960 com.android.server.wm.WindowManagerService.updateRotationUnchecked:4255 com.android.server.wm.WindowManagerService.updateRotation:4236 com.android.server.wm.DisplayRotation旋转动画停顿一下 android 手机旋转动画_android源码系统OrientationListener.onProposedRotationChanged触发了旋转屏幕动画的
那么它自己又是被谁触发的呢?
这里其实可以考虑把Proto堆栈改长一点获取如下

其实是SystemSensorManager$SensorEventQueue.dispatchSensorEvent触发调用过来的,反正大家清楚旋转屏幕触发源头就是sensor就行。然后跟着这个堆栈一直追既可以到startFreezingDisplayLocked,这个方法代表是冻屏,一般要进行屏幕整个旋转,肯定需要冻屏方便让我们整体画面进行动画

上面我们只是简单知道了动画类ScreenRotationAnimation创建的调用流程,其实还是有比较多的疑问的:
1、难道任何画面都要进行旋转动画么?
哈哈这个其实可以对比一个画面会旋转的Activity和画面不旋转的activity,从日志中获得一些答案
如果画面会旋转打印如下:

如果画面不会旋转打印如下:

对比明显发现画面不会旋转没有发打印WindowManager: Display id=0 rotation changed ,

代码其实如下:

旋转动画停顿一下 android 手机旋转动画_动画_02

有打印即代表rotation有变化,但是他们物理操作都是一样,这个时候都是横屏了
再往上看对比日志:
有旋转情况:
V WindowManager: Computed rotation=ROTATION_90 (1) for display id=0 based on lastOrientation=SCREEN_ORIENTATION_UNSPECIFIED (-1) and oldRotation=ROTATION_0 (0)
这里直接计算为了ROTATION_90,即代表可以旋转,新角度是ROTATION_90
五旋转情况:
V WindowManager: Computed rotation=ROTATION_0 (0) for display id=0 based on lastOrientation=SCREEN_ORIENTATION_NOSENSOR (5) and oldRotation=ROTATION_0 (0)
这里依旧是ROTATION_0,和以前oldRotation属于一样故不需要旋转
但他们唯一差别lastOrientation=SCREEN_ORIENTATION_NOSENSOR lastOrientation=SCREEN_ORIENTATION_UNSPECIFIED (-1)
这个其实就是和activity自己进行设置的一个属性,可以manifest也可以代码指定,所以说应用的设置也会影响是否触发旋转

2、难道传感器一直运行么?我要是没有开屏幕自动旋转呢?如果还工作是不是不合理

这个我可以看看关闭状态栏的中的屏幕自动旋转开关

旋转动画停顿一下 android 手机旋转动画_动画_03

但是关闭了,虽然没看到activity旋转了,依然旋转屏幕发现有如下打印:

04-05 21:41:42.044 563 581 V WindowManager: onProposedRotationChanged, rotatinotallow=1

有这句打印说明传感器就一定工作着,那这个为啥,要怎么才可以关闭传感器?

其实这里我们可以从frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java的

needSensorRunning开始分析:

说白了就是还有个setting值
public static final String SHOW_ROTATION_SUGGESTIONS = “show_rotation_suggestions”;
也是为true
即是否显示旋转建议,可以把它手动变为0既可以

关键代码都有注释:
看到ScreenRotationAnimation构造最主要工作就是创建了一个截图的mScreenshotLayer,并且显示再最上面层级, 但是大家注意哈,这里的构造中setRotation其实没有干啥哈,因为角度还没有变化,这里大家要注意不要被网络其他文章带偏。
在屏幕旋转后摆放截图位置部分需要理解一点预备知识:
因为屏幕旋转,肯定显示位置要发生变化的具体如下图

旋转动画停顿一下 android 手机旋转动画_android源码系统_04

注意:
真正的摆放截图位置的触发是由sendNewConfiguration里面触发的,这里才会有最新的rotation和新的rotation进行deta插值,具体调用堆栈如下:

具体的代码:

什么时候开始启动屏幕动画呢?前面相当于都是构造相关类,和对画面进行矩阵位置旋转,还没有看到动画?这里我们用wms课程老方法,我们知道只要是动画一般都会创建对应的leash图层,看看leash堆栈:

可以看得出这里其实performSurfacePlacementNoTrace,只要所有参与动画窗口都已经根据最新configration准备好了(具体关注后期文章专门分析解冻条件),开始会进行解冻,解冻时候调用ScreenRotationAnimation.dismiss方法进行对应的旋转屏幕动画的触发,下面主要来从dismiss开始看:

下面来看关键的startAnimation

下面来看startScreenRotationAnimation

好上面执行完基本就和之前窗口动画都一样了,这里我们放慢动画过程截取某一个阶段看看:

旋转动画停顿一下 android 手机旋转动画_f<em></em>ramework_05

明显RotationLayer属于截图Layer,后面Activity属于DisplayContent的Layer,DisplayContent这个图层Layer执行动作是竖屏到横屏旋转,而ShotscreenLayer明显是又是横屏到竖屏的过程,具体可以看课程视频动画,这里blog就不上动画过程了

本文地址:http://keair.bhha.com.cn/quote/9292.html    康宝晨 http://keair.bhha.com.cn/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


相关最新动态
推荐最新动态
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  粤ICP备2023022329号