本文作者
作者:HiDhl
链接:
https://juejin.im/post/6844904180306411528
本文由作者授权发布。
直面底层系列文章上期:
直面底层:Android 渲染机制, Choreographer 必须得了解
1 引言
这是 Android 10 源码分析系列
分支:android-10.0.0_r14
全文阅读大概 10 分钟
在之前的文章 0xA06 Android 10 源码分析:WindowManager 视图绑定以及体系结构 介绍了 Activity、Window、PhoneWindow、WindowManager 之间的关系,以及 Activity 和 Dialog 的视图绑定过程,而这篇文章主要两个目的:
对上一篇文章 0xA06 Android 10 源码分析:WindowManager 视图绑定以及体系结构 做深入的了解
为后面的篇文章「如何在 Andorid 系统里添加自定义 View」等等做好铺垫
通过这篇文章你将学习到以下内容,将在文末总结部分会给出相应的答案
Window 都有那些常用的参数?
Window 都那些类型?每个类型的意思?以及作用?
Window 那些过时的 API 以及处理方案?
Window 视图层级顺序是如何确定的?
Window 都那些 flag?每个 flag 的意思?以及作用?
Window 的软键盘模式?每个模式的意思?以及如何使用?
Kotlin 小技巧?
在开始分析之前,我们先来看一张图,熟悉一下几个基本概念,这些概念伴将随着整篇文章
我们在手机上看到的界面是二维的,但是实际上是一个三维,如上图所示
Window:是一个抽象类,它作为一个顶级视图添加到 WindowManager 中,View 是依附于 Window 而存在的,对 View 进行管理
WindowManager:它是一个接口,继承自接口 ViewManager,对 Window 进行管理
PhoneWindow:Window 唯一实现类,添加到 WindowManager 的根容器中
WindowManagerService:WindowManager 是 Window 的容器,管理着 Window,对 Window 进行添加和删除,最终具体的工作都是由 WindowManagerService 来处理的,WindowManager 和 WindowManagerService 通过 Binder 来进行跨进程通信,WindowManagerService 才是 Window 的最终管理者
这篇文章重要知识点是 Window 视图层级顺序是如何确定的,其他内容都是一些概念的东西,可以选择性的阅读,了解完基本概念之后,进入这篇文章的核心内容,我们先来了解一下Window 都有哪些常用的参数。
2 Window 都有哪些常用的参数Window 的参数都被定义在 WindowManager 的静态内部类 LayoutParams 中
frameworks/base/core/java/android/view/WindowManager#LayoutParams.java
public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
// window 左上角的 x 坐标
public int x;
// window 左上角的 y 坐标
public int y;
// Window 的类型
public int type;
// Window 的 flag 用于控制 Window 的显示
public int flags;
// window 软键盘输入区域的显示模式
public int softInputMode;
// window 的透明度,取值为0-1
public float alpha = 1.0f;
// window 在屏幕中的位置
public int gravity;
// window 的像素点格式,值定义在 PixelFormat 中
public int format;
}
接下来我们我们主要来介绍一下 Window 的类型、Window 视图层级顺序、Window 的 flag、和 window 软键盘模式.
3 Window 都那些类型以及作用Window 的类型大概可以分为三类:
应用程序 Window(Application Window)
子 Window(Sub Windwow)
系统 Window(System Window)
Window 的类型通过 type 值来表示,每个大类型又包含多个小类型,它们都定义在 WindowManager 的静态内部类 LayoutParams
frameworks/base/core/java/android/view/WindowManager#LayoutParams.java
public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
public int type;
// 应用程序 Window 的开始值
public static final int FIRST_APPLICATION_WINDOW = 1;
// 应用程序 Window 的结束值
public static final int LAST_APPLICATION_WINDOW = 99;
// 子 Window 类型的开始值
public static final int FIRST_SUB_WINDOW = 1000;
// 子 Window 类型的结束值
public static final int LAST_SUB_WINDOW = 1999;
// 系统 Window 类型的开始值
public static final int FIRST_SYSTEM_WINDOW = 2000;
// 系统 Window 类型的结束值
public static final int LAST_SYSTEM_WINDOW = 2999;
}
类型 | 值 | 备注 |
---|---|---|
FIRST_APPLICATION_WINDOW | 1 | 应用程序 Window 的开始值 |
LAST_APPLICATION_WINDOW | 99 | 应用程序 Window 的结束值 |
FIRST_SUB_WINDOW | 1000 | 子 Window 的开始值 |
LAST_SUB_WINDOW | 1999 | 子 Window 的结束值 |
FIRST_SYSTEM_WINDOW | 2000 | 系统 Window 的开始值 |
LAST_SYSTEM_WINDOW | 2999 | 系统 Window 的结束值 |
小技巧:如果是层级在 2000(FIRST_SYSTEM_WINDOW)以下的是不需要申请弹窗权限的。
应用程序 Window(Application Window):它的区间范围 [1,99],例如 Activity
frameworks/base/core/java/android/view/WindowManager#LayoutParams.java
// 应用程序 Window 的开始值
public static final int FIRST_APPLICATION_WINDOW = 1;
// 应用程序 Window 的基础值
public static final int TYPE_BASE_APPLICATION = 1;
// 普通的应用程序
public static final int TYPE_APPLICATION = 2;
// 特殊的应用程序窗口,当程序可以显示 Window 之前使用这个 Window 来显示一些东西
public static final int TYPE_APPLICATION_STARTING = 3;
// TYPE_APPLICATION 的变体,在应用程序显示之前,WindowManager 会等待这个 Window 绘制完毕
public static final int TYPE_DRAWN_APPLICATION = 4;
// 应用程序 Window 的结束值
public static final int LAST_APPLICATION_WINDOW = 99;
类型 |
备注 |
---|---|
FIRST_APPLICATION_WINDOW | 应用程序 Window 的开始值 |
TYPE_BASE_APPLICATION | 应用程序 |