android7.0多窗口横屏模式下statusbar有条纹

2023-12-20 10:18

本文主要是介绍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的源代码
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有条纹的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/515657

相关文章

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

大数据spark3.5安装部署之local模式详解

《大数据spark3.5安装部署之local模式详解》本文介绍了如何在本地模式下安装和配置Spark,并展示了如何使用SparkShell进行基本的数据处理操作,同时,还介绍了如何通过Spark-su... 目录下载上传解压配置jdk解压配置环境变量启动查看交互操作命令行提交应用spark,一个数据处理框架

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

Python实现多路视频多窗口播放功能

《Python实现多路视频多窗口播放功能》这篇文章主要为大家详细介绍了Python实现多路视频多窗口播放功能的相关知识,文中的示例代码讲解详细,有需要的小伙伴可以跟随小编一起学习一下... 目录一、python实现多路视频播放功能二、代码实现三、打包代码实现总结一、python实现多路视频播放功能服务端开

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

迭代器模式iterator

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/iterator 不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素