Android(安卓)8.1 FreeForm切换显示异常
16lz
2021-01-24
平台
RK3399 + Android 8.1
调试应用: com.android.documentsui
问题
- 切换后显示异常, 如下图所示, 窗口明显被拉伸了:
- 正确的显示效果:
调试
dumpsys window
- 显示异常
Window #5 Window{82f86c3 u0 com.android.documentsui/com.android.documentsui.files.FilesActivity}: mDisplayId=0 stackId=2 mSession=Session{8e3c127 1593:u0a10012} [email protected] mOwnerUid=10012 mShowToOwnerOnly=true package=com.android.documentsui appop=NONE mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#10 ty=1 fl=#81810100 pfl=0x20000 fmt=-3 wanim=0x10302f6 vsysui=0x600 surfaceInsets=Rect(40, 40 - 40, 40) (manual) (!preservePreviousSurfaceInsets) needsMenuKey=2 colorMode=0} Requested w=960 h=512 mLayoutSeq=577 mHasSurface=true mShownPosition=[484,90] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false WindowStateAnimator{a17f258 com.android.documentsui/com.android.documentsui.files.FilesActivity}: mAnimating=true mLocalAnimating=false mAnimationIsEntrance=false mAnimation=null mStackClip=1 XForm: has=true hasLocal=false {alpha=1.0 matrix=[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]} Surface: shown=true layer=21010 alpha=1.0 rect=(444.0,50.0) 1040.0 x 592.0 transform=(0.99166936, 0.0, 1.5310801, 0.0) mGlobalScale=1.0 mDsDx=0.99166936 mDtDx=0.0 mDtDy=0.0 mDsDy=1.5310801 isOnScreen=true isVisible=true
- 正常显示
Window #5 Window{82f86c3 u0 com.android.documentsui/com.android.documentsui.files.FilesActivity}: mDisplayId=0 stackId=2 mSession=Session{8e3c127 1593:u0a10012} [email protected] mOwnerUid=10012 mShowToOwnerOnly=true package=com.android.documentsui appop=NONE mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#10 ty=1 fl=#81810100 pfl=0x20000 fmt=-3 wanim=0x10302f6 vsysui=0x600 surfaceInsets=Rect(40, 40 - 40, 40) (manual) (!preservePreviousSurfaceInsets) needsMenuKey=2 colorMode=0} Requested w=960 h=512 mLayoutSeq=595 mHasSurface=true mShownPosition=[480,256] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false WindowStateAnimator{a17f258 com.android.documentsui/com.android.documentsui.files.FilesActivity}: Surface: shown=true layer=21010 alpha=1.0 rect=(440.0,216.0) 1040.0 x 592.0 transform=(1.0, 0.0, 1.0, 0.0) isOnScreen=true isVisible=true
从近期任务切换为FreeForm模式:
com.android.server.am.ActivityManagerService.startActivityFromRecents(ActivityManagerService.java:4935)com.android.server.am.ActivityStackSupervisor.startActivityFromRecentsInner(ActivityStackSupervisor.java:4882)com.android.server.wm.WindowManagerService.continueSurfaceLayout(WindowManagerService.java:2979)com.android.server.wm.WindowSurfacePlacer.continueLayout(WindowSurfacePlacer.java:126)com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:135)com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:145)com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:197)com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:608)com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction(RootWindowContainer.java:865)com.android.server.wm.DisplayContent.applySurfaceChangesTransaction(DisplayContent.java:2784)com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:633)com.android.server.wm.DisplayContent.forAllWindows(DisplayContent.java:1533)com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:616)com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:616)com.android.server.wm.WindowState.forAllWindows(WindowState.java:4034)com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4127)com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:777)com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:779)
- AppWindowAnimator.java
com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:623)com.android.server.wm.WindowSurfacePlacer.handleAppTransitionReadyLocked(WindowSurfacePlacer.java:344)com.android.server.wm.WindowSurfacePlacer.handleOpeningApps(WindowSurfacePlacer.java:404)com.android.server.wm.AppWindowToken.setVisibility(AppWindowToken.java:372)com.android.server.wm.WindowManagerService.applyAnimationLocked(WindowManagerService.java:2435)com.android.server.wm.AppWindowAnimator.setAnimation(AppWindowAnimator.java:127)
在APP切换动画启动后,
DisplayContent WindowSta applySurfaceChangesTransaction computeShownFrameLocked DisplayContent WindowSta-
WindowStateAnimator中计算并重新设置上面dump出来的相关变量: mShownPosition 和 transform
-
问题的根源在于 startProlongAnimation 调用了, 但 endProlongedAnimation 却迟迟未调用, 导致动画被无限推后, mShownPosition 和 transform 也一直无变化:
-
AppWindowAnimator
/** * Sometimes we need to synchronize the first frame of animation with some external event, e.g. * Recents hiding some of its content. To achieve this, we prolong the start of the animaiton * and keep producing the first frame of the animation. */ private long getAnimationFrameTime(Animation animation, long currentTime) { if (mProlongAnimation == PROLONG_ANIMATION_AT_START) { animation.setStartTime(currentTime); return currentTime + 1; } return currentTime; } private boolean stepAnimation(long currentTime) { if (animation == null) { return false; } transformation.clear(); final long animationFrameTime = getAnimationFrameTime(animation, currentTime);...}void startProlongAnimation(int prolongType) { if(!ffNoCaption)mProlongAnimation = prolongType; mClearProlongedAnimation = false; } void endProlongedAnimation() { mProlongAnimation = PROLONG_ANIMATION_DISABLED; }
RecentsActivity WindowMana AppWindowAnimator endProlongedAnimations endProlongedAnimations endProlongedAnimation RecentsActivity WindowMana AppWindowAnimator - WindowManagerService.java
@Override public void endProlongedAnimations() { synchronized (mWindowMap) { for (final WindowState win : mWindowMap.values()) { final AppWindowToken appToken = win.mAppToken; if (appToken != null && appToken.mAppAnimator != null) { appToken.mAppAnimator.endProlongedAnimation(); } } mAppTransition.notifyProlongedAnimationsEnded(); } }
加上调试LOG后输出:
//开始切换:05-30 05:13:25.287 D/AppWindowAnimator 497): startProlongAnimation 8026179405-30 05:13:25.298 D/RecentsActivity( 670): addOnPreDrawListener 205-30 05:13:25.301 D/RecentsActivity( 670): onPreDraw//从mWindowMap 中删除 com.android.documentsui05-30 05:13:25.309 D/WindowManagerService( 497): postWindowRemoveCleanupLocked remove com.android.documentsui/com.android.documentsui.files.FilesActivity05-30 05:13:25.336 D/RecentsActivity( 670): Recents.getSystemServices().endProlongedAnimations();//开始遍历并调用 AppWindowAnimator.endProlongedAnimation05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=com.android.systemui/com.android.systemui.recents.RecentsActivity05-30 05:13:25.337 D/AppWindowAnimator( 497): endProlongedAnimation 4322140005-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=NavigationBar05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=NavigationBar mAppAnimator is NULL05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=AssistPreviewPanel05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=AssistPreviewPanel mAppAnimator is NULL05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=DockedStackDivider05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=DockedStackDivider mAppAnimator is NULL05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=com.android.launcher3/com.android.launcher3.Launcher05-30 05:13:25.337 D/AppWindowAnimator( 497): endProlongedAnimation 7329598905-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=StatusBar05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=StatusBar mAppAnimator is NULL05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=com.android.systemui.ImageWallpaper05-30 05:13:25.337 D/WindowManagerService( 497): endProlongedAnimations win.mAppToken.stringName=com.android.systemui.ImageWallpaper mAppAnimator is NULL//重新将 com.android.documentsui 加入 mWindowMap 中05-30 05:13:25.404 D/WindowManagerService( 497): addWindow com.android.documentsui/com.android.documentsui.files.FilesActivity
从调试的LOG看, 对应com.android.documentsui的Window在循环调用 AppWindowAnimator.endProlongedAnimation时, 完美地错过了…
解决:
- frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) { int[] appOp = new int[1]; int res = mPolicy.checkAddPermission(attrs, appOp);//...省略代码... } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { atoken = token.asAppWindowToken();//增加代码if(atoken != null && atoken.mAppAnimator != null){atoken.mAppAnimator.endProlongedAnimation();}//....省略代码....
更多相关文章
- HTML颜色代码表
- android中一种欢迎界面模式
- 说说在 Android(安卓)中如何发送自定义广播
- android NoSuchMethodError getDrawable
- android在处理一写图片资源的时候,会进行一些类型的转换,现在有空
- Android(安卓)DynamicLoadApk 开源插件开发项目代码剖析
- Android(安卓)EditText软键盘弹出时防止布局上移和关闭软键盘
- Android——动态广播、静态广播
- 背景图片显示问题 图片显示错误 android开发