Android的Window和WindowManager

来源:互联网 发布:清代后宫 知乎 编辑:程序博客网 时间:2024/05/22 12:04

转载自:http://blog.csdn.net/yhaolpz/article/details/68936932

WindowManagerService

Window是一个抽象类,表示一个窗口,具体实现类时PhoneWindow,实现位于WindowManagerService中。

WindowManagerService就是位于Framework层的窗口管理服务,它的职责是管理系统所有窗口。窗口本质在android中就是绘制的画布:Surface。
根据对 Surface 的操作类型可以将 Android 的显示系统分为三个层次:
这里写图片描述

一般的开发过程中,我们操作的是 UI 框架层,对 Window 的操作通过 WindowManager 即可完成,而 WindowManagerService 作为系统级服务运行在一个单独的进程,所以 WindowManager 和 WindowManagerService 的交互是一个 IPC 过程。

Window分类

Window 有三种类型,分别是应用 Window、子 Window 和系统 Window。应用类 Window 对应一个 Acitivity,子 Window 不能单独存在,需要依附在特定的父 Window 中,比如常见的一些 Dialog 就是一个子 Window。系统 Window是需要声明权限才能创建的 Window,比如 Toast 和系统状态栏都是系统 Window。

Window 是分层的,每个 Window 都有对应的 z-ordered,层级大的会覆盖在层级小的 Window 上面,这和 HTML 中的 z-index 概念是完全一致的。在三种 Window 中,应用 Window 层级范围是 1~99,子 Window 层级范围是 1000~1999,系统 Window 层级范围是 2000~2999,我们可以用一个表格来直观的表示:

Window 层级

应用window 1~99
子Window 1000~1999
系统Window 2000~2999

这些层级范围对应着 WindowManager.LayoutParams 的 type 参数,如果想要 Window 位于所有 Window 的最顶层,那么采用较大的层级即可,很显然系统 Window 的层级是最大的,当我们采用系统层级时,需要声明权限。

WindowManager 使用

我们对 Window 的操作是通过 WindowManager 来完成的,WindowManager 是一个接口,它继承自只有三个方法的 ViewManager 接口:

public interface ViewManager{    public void addView(View view, ViewGroup.LayoutParams params);    public void updateViewLayout(View view, ViewGroup.LayoutParams params);    public void removeView(View view);}

这三个方法其实就是 WindowManager 对外提供的主要功能,即添加 View、更新 View 和删除 View。接下来来看一个通过 WindowManager 添加 Window 的例子,代码如下:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Button floatingButton = new Button(this);        floatingButton.setText("button");        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(                WindowManager.LayoutParams.WRAP_CONTENT,                WindowManager.LayoutParams.WRAP_CONTENT,                0, 0,                PixelFormat.TRANSPARENT        );        // flag 设置 Window 属性        layoutParams.flags= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;        // type 设置 Window 类别(层级)        layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;        layoutParams.gravity = Gravity.CENTER;        WindowManager windowManager = getWindowManager();        windowManager.addView(floatingButton, layoutParams);    }}

代码中并没有调用 Activity 的 setContentView 方法,而是直接通过 WindowManager 添加 Window,其中设置为系统 Window,所以应该添加权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

这里写图片描述

第二个界面是锁屏界面,由于按钮是处于较大层级的系统 Window 中的,所以可以看到 button。

WindowManager 的内部机制

原创粉丝点击