注意:Android 12的代码Google已经释放出来了,针对这个问题也做了类似的修改,可以参考Android 12上做出修改。
Android 11平台出现一个随机性问题,灭屏然后亮屏后解锁,界面会闪现一个后台应用的界面,只要出现以后除非清除此后台应用或者重启,否则就一直存在此问题。此问题为概率性问题,故我追踪了很长时间才找到此问题原因。
一.问题原因:
从抓取的问题log来看,很容易就看出来如下:
Window{fd7df20 u0 com.google.android.gm/com.google.android.gm.welcome.WelcomeTourActivity EXITING}
WelcomeTourActivity的WindowState一直处于EXITING状态,也就是说WindowState的属性mAnimatingExit一直等于true。其在解锁一瞬间出现的原因如下,以下为我模拟的一个出现问题的场景:
1.产生问题的WindowState在灭屏,dumpsys window。其问题信息如下:
Window #11 Window{187f8b8 u0 com.pc.pcconnector/com.pc.pcconnector.MainActivity EXITING}:
mDisplayId=0 rootTaskId=9 mSession=Session{1b1be15 5996:u0a10174} mClient=android.os.BinderProxy@565af1b
mOwnerUid=10174 showForAllUsers=false package=com.pc.pcconnector appop=NONE
mAttrs={(0,0)(fillxfill) sim={adjust=pan forwardNavigation} ty=BASE_APPLICATION wanim=0x10302fe
fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED
fitSides=}
Requested w=720 h=1560 mLayoutSeq=305
canReceiveKeys()=false mHasSurface=true isReadyForDisplay()=false mWindowRemovalAllowed=false
WindowStateAnimator{225af2a com.pc.pcconnector/com.pc.pcconnector.MainActivity}:
Surface: shown=false layer=0 alpha=1.0 rect=(0.0,0.0) 720 x 1560 transform=(1.0, 0.0, 1.0, 0.0)
mAnimatingExit=true mRemoveOnExit=false mDestroying=false mRemoved=false
mForceSeamlesslyRotate=false seamlesslyRotate: pending=null finishedFrameNumber=0
isOnScreen=false
isVisible=false
由以上信息可以看到,其重要的属性有:mHasSurface=true,mAnimatingExit=true,mDestroying=false,isOnScreen=false,isVisible=false。
2.亮屏,解锁,闪现问题WindowState
Window{187f8b8 u0 com.pc.pcconnector/com.pc.pcconnector.MainActivity EXITING}时,dumpsys window:
其属性有变化的为:isOnScreen=true。
查看其源码如下:
/**
* Is this window currently on-screen? It is on-screen either if it
* is visible or it is currently running an animation before no longer
* being visible.
*/
boolean isOnScreen() {
if (!mHasSurface || mDestroying || !isVisibleByPolicy()) {
return false;
}
final ActivityRecord atoken = mActivityRecord;
if (atoken != null) {
return ((!isParentWindowHidden() && atoken.mVisibleRequested)
|| isAnimating(TRANSITION | PARENTS));
}
return !isParentWindowHidden() || isAnimating(TRANSITION | PARENTS);
}
因为解锁时,WMS会进行AppTransition,此时由于是处于解锁状态,DisplayContent.mClosingApps.isEmpty,故此时系统的最终过渡动画指向的目标为DefaultTaskDisplayArea,此时流程如下:
(1)解锁后进行DefaultTaskDisplayArea的过度动画:
22:41:04.540 Starting animation on DefaultTaskDisplayArea@242807855: type=1, anim=com.android.server.wm.LocalAnimationAdapt