Android WindowManager

一、WindowManager介绍

Android显示子系统的核心是WindowManager,它负责管理窗口,并将应用的用户界面显示在屏幕上。Surface Manager则负责管理应用的一些低层次的图形操作,例如图像合成、渲染和硬件加速等。View System则是实现具体显示逻辑的部分,它负责显示控制、布局和视图等元素。DisplayManager则是管理Android设备上所有显示器的一种服务,它提供了对显示器的基本设置和控制,包括分辨率、方向、亮度等功能,如下为WindowManager相关类图:

1、Window 是一个抽象概念,代表一个窗口,其具体的实现类为 PhoneWindow ,它对 View进行管理。

2、WindowManager 是一个接口类,继承自接口 ViewManager,它是用来管理 Window 的。

3、WindowManagerImpl是WindowManager的一个具体实现类,它实现了WindowManager定义的所有接口。

4、WindowManagerGlobal 是实际操作的类,是一个单例,每个进程中只有一个实例对象,该实例对象在 WindowManagerGlobal 中。

5、在 WindowManagerGlobal 中,会创建 ViewRootImpl 实例对象,每个根 View 对应一个 ViewRootImpl 实例对象。

6、ViewRootImpl 实现了 View 和 WindowManager 之间所需要的协议,ViewRootImpl 的创建过程是从 WindowManagerImpl 中开始的。View 的测量,布局,绘制以及上屏,都是从 ViewRootImpl 中开始的。

二、WindowManager相关类和接口

IWindow

IWindow接口负责管理窗口的创建、布局、显示、隐藏等操作,包含以下几个核心方法:

1、createWindow:创建一个新的窗口,并返回该窗口的ID。

2、removeWindwo:删除一个指定ID的窗口。

3、layoutWindow:对一个指定ID的窗口进行布局操作,包括位置和大小的设置。

4、showWindow:将一个指定ID的窗口显示出来。

5、hideWindow:将一个指定的窗口隐藏起来。

IWindow接口是系统级别的接口,应用程序不需要直接使用IWindow接口,而可以使用WindowMagager提供的接口来操作窗口。

IWindow代码位于:

frameworks/base/core/java/android/view/IWindow.aidl

IWindow的定义:

oneway interface IWindow {}

IWindowId

IWindowId接口是Android系统中的一个接口,它提供了获取窗口ID的方法,用于唯一标识在WindowManager中的一个窗口。每个窗口在创建的时候都会分配一个唯一的ID,该ID在应用程序生命周期内是始终有效的。可以使用该ID查找、更新或删除与其相关联的窗口,IWindowId接口的主要使用类为WindowManagerGlobal,实现类为WindowManagerService中WindowState。

IWindowId代码位于:

frameworks/base/core/java/android/view/IWindowId.aidl

IWindowId的定义:

interface IWindowId{}

IWindowSession

IWindowSession是用于客户端和WindowManagerService之间进行窗口管理操作的接口,用于向WindowManagerService发送请求,包括以下常用方法:

1、addToDisplay:将一个窗口添加到指定的显示器上。

2、remove:从窗口中删除指定的窗口。

3、setFlags:设置指定窗口的标志位。

4、setInsets:设置窗口的插图。

5、setLayout:设置指定窗口的布局参数,例如大小、位置和对齐方式。

6、setTransparentRegion:设置指定窗口的透明区域。

7、prepareToReplaceWindows:准备开始移除旧窗口并添加新窗口。

8、relayout:重新布局指定窗口,并返回新的布局参数。

IWindowSession代码位于:

frameworks/base/core/java/android/view/IWindowSession.aidl

IWindowSession的定义:

interface IWindowSession {}

IWindowSessionCallback

IWindowSessionCallback是用于WindowManagerService和客户端之间进行通信的接口,用于向客户端发送来自WindowManagerService的响应,包括以下常用方法:

1、windowCreated:通知客户端一个新的窗口已经被创建。

2、windowMoved:通知客户端一个窗口已经被移动到指定位置。

3、windowResized:通知客户端一个窗口已经被调整大小。

4、windowVisibilityChanged:通知客户端一个窗口的可见性已经发生了改变。

5、windowFocusChanged:通知客户端窗口焦点已经发生了变化。

6、windowDied:通知客户端一个窗口已经被销毁。

7、windowInsetsChanged:通知客户端一个窗口的插图已经发生了变化。

IWindowSessionCallback代码位于:

frameworks/base/core/java/android/view/IWindowSessionCallback.aidl

IWindowSessionCallback的定义:

oneway interface IWindowSessionCallback{}

IWindowFocusObserver

IWindowFocusObserver是Android系统中的一个接口,它用于监控窗口焦点变化事件的回调,实现该接口需要重写windowFocusChanged()方法,该方法会在窗口焦点发生变化时被回调,传递包含当前窗口焦点状态的参数,IWindowFocusObserver的调用类是WindowManagerService中WindowState,一般情况下,只有系统服务和一些系统组件(例如Launcher)才会注册IWindowFocusObserver。

IWindowSessionCallback代码位于:

frameworks/base/core/java/android/view/IWindowFocusObserver.aidl

IWindowFocusObserver的定义:

interface IWindowFocusObserver{}

IWindowManager

IWindowManage负责协调及控制所有窗口的位置、大小、层级关系等属性,以及处理窗口相关的输入事件,包含以下几个核心方法:

1、addView:向WindowManager中添加一个新的视图,用于在屏幕上显示。

2、removeView:从WindowManager中删除指定的视图。

3、updateViewLayout:更新指定视图的布局参数。

4、getWindowManagerDefaultDisplay:获取默认显示器的Display对象。

5、getDefaultDisplayRotation:获取显示器方向。

6、lockNow:锁定屏幕。

7、setRotation:设置显示器的朝向。

8、freezeRotation:冻结显示器的朝向。

IWindowManage接口是系统级别的接口,一般而言,应用程序不应该直接IWindowManage接口,而可以使用WindowMagager提供的接口来操作窗口。

IWindowManager代码位于:

frameworks/base/core/java/android/view/IWindowManager.aidl

IWindowManager的定义:

interface IWindowManager{}

WindowManager

WindowManager是Android系统中的一个重要组件,它是外界访问Window的入口。具体来说,WindowManager负责管理和控制应用程序窗口的显示和操作。WindowManager的具体实现位于WindowManagerService中。

WindowManager文件路径:

frameworks/base/core/java/android/view/WindowManager.java

WindowManager定义:

public interface WindowManager extends ViewManager {
    @interface DisplayImePolicy {}
    public interface KeyboardShortcutsReceiver {}
    public static class BadTokenException extends RuntimeException {}
    public static class InvalidDisplayException extends RuntimeException {}
    public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {}
}

WindowManager方法:

public void removeViewImmediate(View view):立即删除视图

default @NonNull WindowMetrics getCurrentWindowMetrics():Returns the {@link WindowMetrics} according to the current system state.

default @NonNull WindowMetrics getMaximumWindowMetrics():Returns the largest {@link WindowMetrics} an app may expect in the current system state.

default boolean isCrossWindowBlurEnabled():Returns whether cross-window blur is currently enabled.

default void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener):Adds a listener, which will be called when cross-window blurs are enabled/disabled at runtime.

default void addCrossWindowBlurEnabledListener(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener):Adds a listener, which will be called when cross-window blurs are enabled/disabled at runtime.

default void removeCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) :Removes a listener, previously added with {@link #addCrossWindowBlurEnabledListener}

public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {}:WindowManager的内部类,继承与ViewGrop.LayoutParams,用于描述窗口的布局参数。

public LayoutParams():构造方法

public void setFitInsetsTypes(@InsetsType int types): Specifies types of insets that this window should avoid overlapping during layout.

public void setFitInsetsSides(@InsetsSide int sides):Specifies sides of insets that this window should avoid overlapping during layout.

public void setFitInsetsIgnoringVisibility(boolean ignore):Specifies if this window should fit the window insets no matter they are visible or not.

public void setTrustedOverlay():Specifies that the window should be considered a trusted system overlay.

public void setSystemApplicationOverlay(boolean isSystemApplicationOverlay):When set on {@link LayoutParams#TYPE_APPLICATION_OVERLAY} windows they stay visible, even if {@link LayoutParams#SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS} is set for another visible window.

public boolean isSystemApplicationOverlay():Returns if this window is marked as being a system application overlay.

public @InsetsType int getFitInsetsTypes():return the {@link WindowInsets.Type}s that this window is avoiding overlapping.

public @InsetsSide int getFitInsetsSides():return the sides that this window is avoiding overlapping.

public boolean isFitInsetsIgnoringVisibility():return {@code true} if this window fits the window insets no matter they are visible or not.

public LayoutParams forRotation(int rotation):

public final void setTitle(CharSequence title):设置标题

public final CharSequence getTitle():获取标题

public final void setSurfaceInsets(View view, boolean manual, boolean preservePrevious):Sets the surface insets based on the elevation (visual z position) of the input view.

public void setColorMode(@ActivityInfo.ColorMode int colorMode):设颜色模式。

public int getColorMode():获取颜色模式。

public void setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius):Blurs the screen behind the window.

public int getBlurBehindRadius():Returns the blur behind radius of the window.

public final void setUserActivityTimeout(long timeout)

public final long getUserActivityTimeout()

public final void setWindowContextToken(@NonNull IBinder token)

public final IBinder getWindowContextToken():gets the {@link android.app.WindowContext} token.

WindowManagerGlobal

WindowManagerGlobal是一个单例类,作为对WindowManager的全局封装,它提供了许多与Window有关的方法。它的主要作用是管理Window的一些全局状态,如屏幕方向、是否显示窗口等。

WindowManagerGlobal文件路径:

frameworks/base/core/java/android/view/WindowManagerGlobal.java

WindowManagerGlobal定义:

public final class WindowManagerGlobal {}

WindowManagerImpl

WindowManagerImpl是WindowManager的一个具体实现类,它实现了WindowManager定义的所有接口。

WindowManagerImpl文件路径:

frameworks/base/core/java/android/view/WindowManagerImpl.java

WindowManagerImpl定义:

public final class WindowManagerImpl implements WindowManager {
    private static class OnFpsCallbackListenerProxy extends ITaskFpsCallback.Stub {}
}

三、WindowManagerService与其他类的关系

1、WindowManager与Window的关系

WindwoManager负责Window的管理,WindowManager可以通过创建、添加、删除、更新等操作来管理各类Window,例如添加应用程序Window、移除DialogWindow、管理Toast消息等。WindowManager还负责给Window分配一些系统资源,例如区域、事件传递等。

Window负责视图的展示,Window是Android系统中最上层的视图容器,在内部包含多个子视图,用于展示应用程序的UI界面。

2、WindowManager与WindowManagerService的关系

WindowManager是Android系统中的一个JAVA类,它负责管理窗口的显示和操作,以及处理的输入事件。而WindowManagerService则是WindowManager的具体实现。

WindowManagerSerive是Android系统中一个系统服务,负责管理窗口和界面的显示和操作,以及处理用户的输入事件。它是Android显示子系统中的一个核心组件,主要有以下几个功能:

管理窗口:负责管理所有窗口的创建、显示、隐藏和销毁等操作。它还能够调整窗口的位置、大小、样式和动画效果等属性,从而确保用户界面的良好体验。

输入事件处理:WindowManagerService能够识别和处理所有传感器和输入设备生成的事件,如触摸、滑动、旋转、按键等。它将这些事件分发到相应的窗口上,让窗口能够及时响应用户的操作,提供用户体验。

屏幕方向和尺寸管理:WindowManagerService能够实时检测设备的方向和尺寸变化,如设备从竖屏变横屏,或者分辨率发生变化等。他会通知窗口进行相应的调整,以适应不同的屏幕和分辨率,保证应用程序的兼容性和互通性。

系统UI管理:WindowManagerService负责管理Android系统中所有的系统UI,如状态栏、导航栏、通知栏、系统对话框等。它能够控制这些系统UI的显示效果和交互方式,以及作为系统级服务为应用程序提供必要的支持。

四、WindowManagerService相关流程分析

我们知道,系统对 Window 进行添加、更新、删除操作,都是通过 WindowManager 来操作的。WindowManager 对 Window 的操作最后都交给 WindowManagerGlobal 来执行。下面我们来分析一下 WindowManagerGlobal 是如何进行 Window 的添加、更新、删除操作的。

WindowManager AddView流程分析

WindowManager的AddView方法用于向WindowManager中添加一个新的视图,并且显示在屏幕上,下面分布进行分析:

1、调用WindowManager的AddView方法,申请添加View。在这个过程中会创建ViewRootImpl对象,并且在ViewRootImpl的构造方法中创建Surface、SurfaceControl和SurfaceSession对象,要注意虽然生成了Surface和SurfaceControl对象,但是因为它没有生成底层的对应的对象,所以是无效的,还不能用于绘制,真正创建Surface的地方在WindowManagerService中。

Android13 WindowManager addView流程分析-CSDN博客

2、调用ViewRootImpl的performTraversals方法,开始View的三大流程(measure、layout、draw)。

Android13 ViewRootImpl performTraversals流程分析-CSDN博客

3、调用View的measure方法,该方法会从DecorView开始按照View树一层一层的进行测量。

Android13 View measure流程分析-CSDN博客

4、调用WindowManagerService的relayoutWindow方法,计算窗口的大小以及内容区域边衬大小和可见区域边衬大小,另外还有创建Surface和SurfaceControl对象用于描画和Surface控制。

Android13 WindowManagerService relayoutWindow流程分析-CSDN博客

5、调用view的layout方法,进行view的布局,这期间可能涉及多次布局。

Android13 View layout流程分析-CSDN博客

6、调用view的draw方法,开始描画。逐级描画,先描画父View(ViewGroup),在描画子View,如果子View还有子View就需要描画子View的子View,以此类推,因此Viw的层级越多,描画的时间就越久。

Android13 View draw流程分析-CSDN博客

7、调用WindowManagerService的addWindow方法,将window添加到wms。

Android13 WindowManagerService addWindow流程分析-CSDN博客

WindowManager updateViewLayout流程分析

1、调用WindowManager的updateViewLayout方法,申请重新布局。

Android13 WindowManager updateViewLayout流程分析-CSDN博客

2、调用调用ViewRootImpl的performTraversals方法,开始View的三大流程(measure、layout、draw)。

Android13 ViewRootImpl performTraversals流程分析-CSDN博客

后面的流程与AddView基本一致,只是不再需要将window添加到wms。

WindowManager removeView流程分析

1、调用WindowManager的removeView方法,申请移除View。

Android13 WindowManager removeView流程分析-CSDN博客

2、调用WindowManagerService的finishDrawingWindwo方法,进行必要的资源销毁。

Android13 WindowManagerService finishDrawingWindow流程分析-CSDN博客

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值