进阶之路 | 奇妙的Window之旅
2021-03-17 23:25
标签:mode 测试 其他 可见 最大化 入口 block uac 管理 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 Window&WindowManagerService Window创建过程 Android手机上所有的视图都是通过 看到下面这张大图,是不是感觉有点乱乱的,别急,别急,心急吃不了热豆腐,笔者将向您娓娓道来 笔者之前在进阶之路 | 奇妙的View之旅中,提及 笔者之前在进阶之路 | 奇妙的View之旅中,提及 每个 想了解IPC的读者,可以看下笔者写的一篇博客: 进阶之路 | 奇妙的 IPC 之旅 Window的具体实现位于 实际使用中无法访问 下面依次介绍 A.应用类 B.子Window:不能单独存在,需附属特定的父Window。如 C.系统Window: 需声明权限才能创建。如 系统权限有很多值,一般选用: 记得声明权限: 这三个方法主要是定义在 一幅图说明这几个类的关系: 因此,通过 不难发现,以上验证了之前的总结: 限于篇幅,笔者这里暂未贴上源码,如果想了解的话,推荐一篇文章:我眼中的Window创建/添加/删除/更新过程 由于 想了解 Q1:Toast的内部的视图由两种方式指定: Q2: Q3:在 Q4: 想了解 恭喜你!已经看完了前面的文章,相信你对 Q1:一个应用中有多少个Window? 答案:无限个。原因:任何一个 Q2:Window对象有存在的必要吗? Q3:Activity有存在的必要吗? 任何事物都有规律,语言再难,也是人发明的,一样具有社会性,其实这几个的关系就像是国家的中央系统的官员分配一样,从古至今,一层对一层负责,这样各司其职,又相互一层层联系着,达到效率最大化,突然发现,古人的智慧还是很厉害的,你让皇帝(系统)去管辖所有的官员(view),岂不是要累死?所以才出现了中间这些“官员” 如果文章对您有一点帮助的话,希望您能点一下赞,您的点赞,是我前进的动力 本文参考链接: 进阶之路 | 奇妙的Window之旅 标签:mode 测试 其他 可见 最大化 入口 block uac 管理 原文地址:https://www.cnblogs.com/xcynice/p/qi_miao_de_window_zhi_lv.html前言
学习清单:
一.为什么要学习
Window
?Window
来呈现的,像常用的Activity
,Dialog
,PopupWindow
,Toast
,他们的视图都是附加在Window
上的,所以可以这么说 ——「Window是View的直接管理者」。Window
是一个顶层窗口查看和行为的一个抽象基类,这个类的实例作为一个顶级View
添加到Window Manager
。它提供了一套标准的UI方法,比如添加背景,标题等等。Window
本身很抽象,深入了解Window
,不仅有助于你了解Android
系统中各个层级之间的关系,还可以对Toast
的内部机制、自定义等等方面会有更加深入的体会。二.核心知识点归纳
2.1 Window关系解析
2.1.1
Window
&PhoneWindow
setContentView
的时候简单说到了Window
和PhoneWindow
,相信看过的读者已经对此有一个简单的印象。Window
是一个抽象类,它定义了顶级窗体样式和行为。其唯一的实现类是PhoneWindow
。2.1.2
Window
&View
View工作流程
的时候简单说到了ViewRootImpl
,相信看过的读者已经对此有一个简单的印象。Window
都对应一个View
和一个ViewRootImpl
,Window
和View
通过ViewRootImpl
来建立联系。Window并不可见,它实际以View的形式存在,它是View
的直接管理者。2.1.3
Window
&WindowManagerService
WindowManagerService
中。WindowManager
和WindowManagerService
的交互是一个IPC
(跨进程通信)过程。2.1.4
Window
&WindowManager
Window
,对Window
的访问必须通过WindowManager
(换句话说,WindowManager
是外界访问Window
的入口),对Window
的操作通过它完成。
WindowManager
添加Window
//将一个Button添加到屏幕为(100,300)的位置
mFloatingButton = new Button(this);
mFloatingButton.setText("test button");
mLayoutParams = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0,PixelFormat.TRANSPARENT);//第三个参数代表flags,第四个参数代表type
mLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE
| LayoutParams.FLAG_SHOW_WHEN_LOCKED;//配置flags
mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR;//配置type
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;//配置gravity
mLayoutParams.x = 100;//相对于gravity
mLayoutParams.y = 300;//相对于gravity
mFloatingButton.setOnTouchListener(this);
mWindowManager.addView(mFloatingButton, mLayoutParams);
WindowManager
的三个重要参数:
flags
:表示Window的属性。主要的可选值含义:
FLAG_NOT_FOCUSABLE
:表示Window
不需要获取焦点,也不需要接收各种输入事件,此标记会同时启动FLAG_NOT_TOUCH_MODEL
,最终事件会传递给下层的具有焦点的Window
。FLAG_NOT_TOUCH_MODAL
:表示系统会将当前Window区域以外的单击事件传递给底层的Window,而区域以内的单击事件则自己处理。一般都需要开启此标记,否则其他Window将无法收到单击事件。FLAG_SHOW_WHEN_LOCKED
:表示Window可显示在锁屏界面。
type
:表示Window
的类型。Window
有三种类型:Window
:对应一个Activity
Dialog
Toast
TYPE_SYSTEM_OVERLAY
/TYPE_SYSTEM_ERROR
,
Android
6.0以下直接声明权限即可,Android6.0
以上还需要用户打开软件设置页手动打开,才能授权。
Window
是分层的,见下表
Window
层级
应用Window
1-99
子Window
1000-1999
系统Window
2000-2999
gravity
:表示Window
的位置。
2.2 Window的内部机制
WindowManager
对Window
主要有三大操作:添加、更新和删除。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
也是一个接口,它继承了ViewManager
接口:public interface WindowManager extends ViewManager {}
WindowManager
的具体实现类是WindowManagerImpl
:public final class WindowManagerImpl implements WindowManager{
@Override
public void addView(View view, ViewGroup.LayoutParams params){
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
@Override
public void updateViewLayout(View view, ViewGroup.LayoutParams params){
mGlobal.updateViewLayout(view, params);
}
@Override
public void removeView(View view){
mGlobal.removeView(view, false);
}
}
WindowManagerImpl
并没有直接实现Window的三大操作,而是交给了WindowManagerGlobal
。WindowManagerGlobal
以单例模式向外提供自己的实例:
WindowManagerImpl
这种工作模式是典型的桥接模式private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
WindowManagerGlobal
的addView()
、updateViewLayout()
、removeView()
实现WindowManager
对Window
的添加、删除和修改。2.2.1
Window
的添加2.2.2
Window
的删除2.2.3
Window
的更新
Window
的三大操作最终都会通过一个IPC过程移交给WindowManagerService
。Window
和View
通过ViewRootImpl
来联系,ViewRootImpl
可控制View
的测量、布局和重绘。2.3
Window
的创建过程
View
必须依附Window
才能呈现出来,因此有View
的地方必有Window
。在Android
中可以提供View
的地方有Activity
、Dialog
和Toast
,PopupWindow
,菜单
,下面分别来看Activity
、Dialog
和Toast
三种Window
的大致创建过程:2.3.1
Activity
的Window
创建过程
Activity
的启动流程这里不了解没关系,笔者后面会专门写一篇文章来介绍
Activity
的Window
创建过程的源码的读者,笔者推荐一篇文章: Activity的Window创建过程分析2.3.2
Dialog
的Window
创建过程
Dialog.show()
方法:完成DecorView
的显示WindowManager.remoteViewImmediate()
方法:当Dialog被dismiss
时移除DecorView2.3.3
Toast
的Window
创建过程
setView()
指定一个自定义ViewToast
具有定时取消功能,故系统采用Handler
做定时处理Toast
内部有两类IPC过程:
Toast
访问NotificationManagerService()
(NotificationManagerService
运行在系统的进程);NotificationManagerService
回调Toast
里的TN
接口(运行在Binder
线程池)。Toast
提供方法show()
和cancel()
分别用于显示和隐藏Toast
。
Toast
的显示和隐藏都需要通过NMS
来实现,由于NMS
运行在系统进程中,故需通过远程调用的方式来进行显示和隐藏Toast。NMS
处理Toast
的显示和隐藏请求时会跨进程回调TN
中的方法,但是由于TN
运行在Binder线程池中,故需通过Handler
将其切换到当前线程(发送Toast请求的线程)。
NMS
只是起到了管理Toast
队列及其延时的效果Toast
的显示和隐藏实际是通过TN
来实现的。
Toast
的Window
创建过程的源码的读者,笔者推荐一篇文章:Android对话框Dialog,PopupWindow,Toast的实现机制三.课堂小测试
Window
已经有一定深度的了解,下面,进行一下课堂小测试,验证一下自己的学习成果吧!View
都是依附在Window
上面,一个应用可以有无限个View
,自然Window
也是无限个。
Window
能做的事情,View
对象基本都能做:像触摸事件、管理各个子View
等等。Window
是View
的管理者”。
WindowManager
是Window
的管理者,那为什么不直接用WindowManager
管理View
呢?View
对象这个说法的!作为系统,我有自己的骄傲,不去管你Window
如何搬砖、如何砌墙,只给你地皮。而这时,Window
为了绘制出用户想要的组件(按钮、文字、输入框等等),系统又不给我!没事,那我自己定义,于是就定义了View
机制,给每个View
提供Canvas
,让不同的View自己绘制具有自己特色的组件。同时,为了更好的管理View
,通过定义ViewGroup
,等等。
Window
已经是系统管理的窗口界面。那么为什么还需要Activity
呢?我们把Activity
所做的事情,全部封装到Window
不就好了?悬浮窗口Dialog
中不就是没有使用Activity
来显示一个悬浮窗吗?Android
中的应用中,里面对各个窗口的管理相当复杂(任务栈、状态等等)。但是如果让用户自己去管理这些Window
,先不说工作量,光让用户自己去实现任务栈这点,就很难了。为了让大家能简单、快速的开发应用,Android
让Activity
帮我们管理好,我们只需简单的去重写几个回调函数,无需直接与Window
对象接触。
文章标题:进阶之路 | 奇妙的Window之旅
文章链接:http://soscw.com/index.php/essay/65521.html