本文主要是介绍android7.0多窗口横屏模式下statusbar有条纹,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Step1 概述
在最近的学习过程中,遇到了一个android7.0原生的缺陷。是关于android7.0新增的分屏功能,久久难以攻克,还是在主管的帮助下,遂记录之,希望以后能少走弯路,高效学习。
Step2 描述
bug详情
General Description:
The notification bar will display stripe when tap the back key on multi-window screen.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Reproducibility:
7/10
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Precondition:
Auto-rotate is on.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Step:
1.Main Menu->Phone->Rotate to landscape mode->Long press RECENT key->Press BACK key->Check the phone displays.
2.Main Menu->Calculator->Rotate to landscape mode->Long press RECENT key->Press BACK key->Check the phone displays.
3.Main Menu->Clock->Rotate to landscape mode->Long press RECENT key->Press BACK key->Check the phone displays.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Actual result:
The notification bar will display stripe when tap the back key on multi-window screen.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expect result:
The notification bar shouldn't display stripe when tap the back key on multi-window screen.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Related Test Case:
N/A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SW version:
36.1.A.0.37
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HW version:
AP2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Step3 查源头
我们打开SystemUI的源代码
这里应该是一个文件夹对应一个模块,比如最近任务,锁屏,电池,截图,状态栏等等。然而我们要关注的是stackdivider,android中会把Activity放到栈中来管理,实际上分屏的话相当于会有一个新的stack,我们看看ActivityManager.java(base/core/java/android/app)文件有个内部类,记录管理着所有的stack
public static class StackId {/** Invalid stack ID. */public static final int INVALID_STACK_ID = -1;/** First static stack ID. */public static final int FIRST_STATIC_STACK_ID = 0;/** Home activity stack ID. */public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID;/** ID of stack where fullscreen activities are normally launched into. */public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;/** ID of stack where freeform/resized activities are normally launched into. */public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;/** ID of stack that occupies a dedicated region of the screen. */public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1;/** ID of stack that always on top (always visible) when it exist. */public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;/** Last static stack stack ID. */public static final int LAST_STATIC_STACK_ID = PINNED_STACK_ID;。。。。。}
知道了这些,我们看看为什么标题栏上会有黑色的条纹,并且是两条,难道是横屏分屏的时候statusbar绘制的时候还有其他的view也被显示了。实际上我们在测试的过程中可以发现
在当前应用屏幕和最近任务屏幕之间有个黑色条纹,可能是这个条纹没有被隐藏掉影响了statusbar的状态。那么我们看看这边的代码
/*** Controls the docked stack divider.*/
public class Divider extends SystemUI {
......@Overrideprotected void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);update(newConfig);}
......
private void update(Configuration configuration) {removeDivider();addDivider(configuration);if (mMinimized) {mView.setMinimizedDockStack(true);updateTouchable();}}
......
......
}
当config change 后会调用update方法,最终看看DividerView的绘制 mView.setMinimizedDockStack(true);
/*** Docked stack divider.*/
public class DividerView extends FrameLayout implements OnTouchListener,OnComputeInternalInsetsListener {......public void setMinimizedDockStack(boolean minimized) {updateDockSide();mHandle.setAlpha(minimized ? 0f : 1f);if (!minimized) {resetBackground();} else if (mDockSide == WindowManager.DOCKED_TOP) {mBackground.setPivotY(0);mBackground.setScaleY(MINIMIZE_DOCK_SCALE);} else if (mDockSide == WindowManager.DOCKED_LEFT|| mDockSide == WindowManager.DOCKED_RIGHT) {mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT? 0: mBackground.getWidth());mBackground.setScaleX(MINIMIZE_DOCK_SCALE);}mMinimizedShadow.setAlpha(minimized ? 1f : 0f);mDockedStackMinimized = minimized;}......private void updateDockSide() {mDockSide = mWindowManagerProxy.getDockSide();mMinimizedShadow.setDockSide(mDockSide);}}
分析上面的code,在最小化分屏界面时会首先执行updateDockSide()方法
public interface WindowManager extends ViewManager {....../** @hide */int DOCKED_INVALID = -1;/** @hide */int DOCKED_LEFT = 1;/** @hide */int DOCKED_TOP = 2;/** @hide */int DOCKED_RIGHT = 3;/** @hide */int DOCKED_BOTTOM = 4;......}
WindowManageProxy下(SystemUI)
public int getDockSide() {try {return WindowManagerGlobal.getWindowManagerService().getDockedStackSide();} catch (RemoteException e) {Log.w(TAG, "Failed to get dock side: " + e);}return DOCKED_INVALID;}
Z:\frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java下
public int getDockedStackSide() {synchronized (mWindowMap) {final TaskStack dockedStack = getDefaultDisplayContentLocked().getDockedStackVisibleForUserLocked();return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();}}
最终是TaskStack getDockSide
回到setMinimizedDockStack方法,会判断dockside,有些情况dockside的值不满足,而这是确实要求隐藏
mMinimizedShadow被異常畫出,
mBackground沒有被隱藏:
(mMinimizedShadow: 阴影view,
mBackground:分割線View )。所以在updatedockside里当是无效的,给他赋值
if(mDockSide == WindowManager.DOCKED_INVALID){mDockSide = WindowManager.DOCKED_TOP;android.util.Log.d("DividerView", "updateDockSide() mDockSide is DOCKED_INVALID change to DOCKED_TOP!");}
Step4总结
搞清楚
这篇关于android7.0多窗口横屏模式下statusbar有条纹的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!