1、背景
【操作步骤】负一屏界面,语音输入:“中文模式/英文模式”
【预期结果】显示正常
【实际结果】
会闪现一下负一屏下层的文字
【发生概率】必现
systemui下拉负一屏界面,通过语音输入:“中文模式/英文模式”,会闪现一下负一屏下层的画面。
2、分析过程
通过逐帧播放视频,我们猜测,bug中的闪屏是指负一屏以下的layer的渐变的动画。
接下来通过动画的调试手段来分析定位问题。
2.1 知识积累:
开发者选项中有三个动画因子
“Window animation scale” :窗口动画缩放
“Transition animation scale” :过渡动画缩放
“Animator duration scale” :动画程序时长缩放
调整动画时长:
adb shell settings get global window_animation_scale
adb shell settings get global transition_animation_scale
adb shell settings get global animator_duration_scale
adb shell settings put global window_animation_scale 10
adb shell settings put global transition_animation_scale 10
adb shell settings put global animator_duration_scale 10
修改白天、黑夜模式:
白天模式 adb shell “su 0 cmd uimode night no”
黑夜模式 adb shell “su 0 cmd uimode night yes”
通过分别设置,发现问题中的现象步骤一,能够清晰的看出来是有一个渐变的动画;
步骤二,现象消失。这能够充分说明,这个问题与android动画有关,需要通过debug animation来定位问题。
adb shell settings put global transition_animation_scale 20
adb shell settings put global transition_animation_scale 0
2.2 如何模拟语言切换中英文:
写一个demo apk,通过广播控制语言切换,切换语言的部分代码如下:
try {
Log.d(TAG, "setLanguage: " + languageCode);
Locale locale = new Locale(languageCode);
Log.d(TAG, "setAppLanguage() start " + locale.toString());
IActivityManager am = ActivityManagerNative.getDefault();
Configuration config = am.getConfiguration();
//config.locale = locale;
config.setLocales(new LocaleList(locale));
config.userSetLocale = true;
am.updatePersistentConfiguration(config);
} catch (android.os.RemoteException e) {
e.printStackTrace();
}
adb shell am broadcast -a android.intent.action.CHANG_LANGUAGE --es code “zh”
adb shell am broadcast -a android.intent.action.CHANG_LANGUAGE --es code “en”
2.3 Android Framework 调试Animation动画的方法
(1)8155(android 11)定位animation问题,如何开启log:
WindowManagerDebugConfig
static final boolean DEBUG_ANIM = false; 设置为true
(2) 如何找到具体是受哪个Animation的影响,导致的问题:
SurfaceAnimator
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
@AnimationType int type,
@Nullable OnAnimationFinishedCallback animationFinishedCallback,
@Nullable SurfaceFreezer freezer) {
Slog.w(TAG, "startAnimation, anim = " + anim + ", hidden = " + hidden + ", t = " + t + ", freezer" + freezer + ", mAnimatable = " + mAnimatable
+ ", sc = " + mAnimatable.getSurfaceControl());
cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
mAnimation = anim;
mAnimationType = type;
mAnimationFinishedCallback = animationFinishedCallback;
final SurfaceControl surface = mAnimatable.getSurfaceControl();
if (surface == null) {
Slog.w(TAG, "Unable to start animation, surface is null or no children.");
cancelAnimation();
return;
}
if (mAnimatable != null && (mAnimatable.toString().contains("SimpleSurfaceAnimatable")
&& surface.toString().contains("RotationLayer"))) {
Slog.w(TAG, "----startAnimation exit-----------", new Throwable("xxxx"));
//Slog.w(TAG, "----startAnimation exit-----------");
//cancelAnimation();
// return;
}
mLeash = freezer != null ? freezer.takeLeashForAnimation() : null;
if (mLeash == null) {
mLeash = createAnimationLeash(mAnimatable, surface, t, type,
mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
0 /* y */, hidden, mService.mTransactionFactory);
mAnimatable.onAnimationLeashCreated(t, mLeash);
}
mAnimatable.onLeashAnimationStarting(t, mLeash);
if (mAnimationStartDelayed) {
if (DEBUG_ANIM) Slog.i(TAG, "Animation start delayed");
return;
}
mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
}
行 78189: 12-31 11:13:59.970 1223 4645 W WindowManager: startAnimation, anim = com.android.server.wm.InsetsSourceProvider$ControlAdapter@896c73d, hidden = true, t = android.view.SurfaceControl$Transaction@e68b403, freezercom.android.server.wm.SurfaceFreezer@ffd88a7, mAnimatable = Window{2bfa2a8 u0 InputMethod}, sc = Surface(name=2bfa2a8 InputMethod)/@0x6c04154
行 78771: 12-31 11:14:00.247 1223 1513 W WindowManager: startAnimation, anim = com.android.server.wm.InsetsSourceProvider$ControlAdapter@917a8b1, hidden = false, t = android.view.SurfaceControl$Transaction@e68b403, freezercom.android.server.wm.SurfaceFreezer@6b73875, mAnimatable = Window{c17a926 u0 BottomCarSystemBar}, sc = Surface(name=c17a926 BottomCarSystemBar)/@0xeb4e00a
行 78795: 12-31 11:14:00.258 1223 1513 W WindowManager: startAnimation, anim = com.android.server.wm.InsetsSourceProvider$ControlAdapter@a2a9d7f, hidden = false, t = android.view.SurfaceControl$Transaction@e68b403, freezercom.android.server.wm.SurfaceFreezer@6bfbf80, mAnimatable = Window{8ddd15a u0 TopCarSystemBar}, sc = Surface(name=8ddd15a TopCarSystemBar)/@0x8fdb9b9
行 79249: 12-31 11:14:00.769 1223 1513 W WindowManager: startAnimation, anim = com.android.server.wm.LocalAnimationAdapter@c3d4ea4, hidden = false, t = android.view.SurfaceControl$Transaction@e68b403, freezernull, mAnimatable = com.android.server.wm.SimpleSurfaceAnimatable@45c3937, sc = Surface(name=mWindowContainers)/@0x24aa028
行 79254: 12-31 11:14:00.769 1223 1513 W WindowManager: startAnimation, anim = com.android.server.wm.LocalAnimationAdapter@a3131d3, hidden = false, t = android.view.SurfaceControl$Transaction@e68b403, freezernull, mAnimatable = com.android.server.wm.SimpleSurfaceAnimatable@617ffc2, sc = Surface(name=RotationLayer)/@0x52b110
一次语言切换,会触发5次动画,一步一步定位是哪个动画导致的问题。
12-31 11:14:00.770 1223 1513 W WindowManager: ----startAnimation exit-----------
12-31 11:14:00.770 1223 1513 W WindowManager: java.lang.Throwable: xxxx
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:153)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:177)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.SurfaceAnimator.startAnimation(SurfaceAnimator.java:182)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.ScreenRotationAnimation$SurfaceRotationAnimationController.startAnimation(ScreenRotationAnimation.java:720)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.ScreenRotationAnimation$SurfaceRotationAnimationController.startScreenshotRotationAnimation(ScreenRotationAnimation.java:634)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.ScreenRotationAnimation$SurfaceRotationAnimationController.startScreenRotationAnimation(ScreenRotationAnimation.java:585)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.ScreenRotationAnimation.startAnimation(ScreenRotationAnimation.java:438)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.ScreenRotationAnimation.dismiss(ScreenRotationAnimation.java:456)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.WindowManagerService.stopFreezingDisplayLocked(WindowManagerService.java:5969)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:922)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:819)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:178)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:127)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:116)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:58)
12-31 11:14:00.770 1223 1513 W WindowManager: at android.os.Handler.handleCallback(Handler.java:938)
12-31 11:14:00.770 1223 1513 W WindowManager: at android.os.Handler.dispatchMessage(Handler.java:99)
12-31 11:14:00.770 1223 1513 W WindowManager: at android.os.Looper.loop(Looper.java:223)
12-31 11:14:00.770 1223 1513 W WindowManager: at android.os.HandlerThread.run(HandlerThread.java:67)
12-31 11:14:00.770 1223 1513 W WindowManager: at com.android.server.ServiceThread.run(ServiceThread.java:44)
3、解决方案
关闭动画解决该问题:(车载项目没有rotation的动作,可以这样做,但是手机或者平板不能这样修改。)