一、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博客