View
、Window
以及Activity
主要是用于显示并与用户交互的。这让我们在初学的时候很容易弄混,而且无法理解他们区别以及联系。本文是笔者查阅相关资料后,结合自己的理解写出来。希望能帮你梳理清楚他们各自的工作职责,以及是因为什么需求导致了它们的出现。
1 View
从我之前写的【从Android代码中来记忆23种设计模式 】这篇文章可知,View
(包括ViewGroup
)使用的是组合模式,即:
将
View
组成成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
我们知道,View
主要是用于绘制我们想要的结果,是一个最基本的UI
组件。
2 Window
2.1 Window的基本理解
简单地说,Window
表示一个窗口,一般来说,Window
大小取值为屏幕大小。但是这不是绝对的,如对话框、Toast
等就不是整个屏幕大小。你可以指定Window的大小。Window
包含一个View tree
和窗口的layout
参数。
感觉Window
的理解比较抽象,我个人的理解是,Window
相当于一个容器,里面“盛放”着很多View
,这些View
是以树状结构组织起来的。
如果你还是无法理解的话,你就把Window
当成是显示器,显示器有大有小(对应Window
有大有小),View
是显示器里面具体显示的内容。
2.2 Window对象有存在的必要吗?
我个人长期有个困惑:Window
能做的事情,View
对象基本都能做:像什么触摸事件啊、显示的坐标及大小啊、管理各个子View
啊等等。View
已经这么强大了,为什么还多此一举,加个Window
对象。可能有人会说因为WindowManager
管理的就是Window
对象呀,那我想问,既然这样,Android
系统直接让WindowManager
去管理View
不就好了?让View
接替Window
的工作,把Window
所做的事情都封装到View
里面不好嘛?(至少免去了我们去理解抽象的Window
,,,,O__O “…)。或许又有人说,View负责绘制显示内容,Window负责管理View,各自的工作职责不同。可是我想说,Window所做的大部分工作,View里面都有同样(或类似)的处理。这依然无法说服我!
关于Window
存在的必要,我查了国内外各种资料,最后有了我个人的理解(如果有错也欢迎评论纠正~)。在后面小节里面,我会结合我个人的理解来解释。在解释之前,我们需要了解Window
绘制过程。
2.3 Window绘制过程
在理解Window
绘制过程之前,首先,我们需要知道Surface
,在Window
中持有一个Surface
,那么什么是Surface
呢?
Surface
其实就是一个持有像素点矩阵的对象,这个像素点矩阵是组成显示在屏幕的图像的一部分。我们看到显示的每个Window
(包括对话框、全屏的Activity
、状态栏等)都有他自己绘制的Surface
。而最终的显示可能存在Window
之间遮挡的问题,此时就是通过Surface Flinger
对象渲染最终的显示,使他们以正确的Z-order
显示出来。一般Surface
拥有一个或多个缓存(一般2个),通过双缓存来刷新,这样就可以一边绘制一边加新缓存。
WindowManager
为每个Window
创建Surface
对象,然后应用就可以通过这个Surface
来绘制任何它想要绘制的东西。而对于WindowManager
来说,这只不过是一块矩形区域而已。
前面我们说过,View
是Window
里面用于交互的UI
元素。Window
只attach
一个View Tree
,当Window
需要重绘(如,当View
调用invalidate
)时,最终转为Window
的Surface
,Surface
被锁住(locked
)并返回Canvas
对象,此时View
拿到Canvas
对象来绘制自己。当所有View
绘制完成后,Surface
解锁(unlock
),并且post
到绘制缓存用于绘制,通过Surface Flinger
来组织各个Window
,显示最终的整个屏幕。
2.4 关于Window对象存在的必要
以下是我个人理解!
现在我们知道了Window
绘制过程,其实,站在系统的角度来考虑,一个Window
对象代表一块显示区域,系统不关心Window
里面具体的绘制内容,也不管你Window
怎么去绘制,反正只给你提供可以在这块区域上绘制图形的Surface
对象,你Window
对象怎么画是你的事情!
换句话说,站在系统的角度上看,系统是“不知道”有View
对象这个说法的!作为系统,我有自己的骄傲,不去管你Window
如何搬砖、如何砌墙,只给你地皮。而这时,Window
为了绘制出用户想要的组件(按钮、文字、输入框等等),系统又不给我!没事,那我自己定义,于是就定义了View
机制,给每个View
提供Canvas
,让不同的View
自己绘制具有自己特色的组件。同时,为了更好的管理View
,通过定义ViewGroup
,等等。
相信看到这,你就知道为什么需要Window
了,当然了,本文并不是去纠缠要不要Window
对象这个问题。而是通过这个问题,让我们理清View
与Window
的区别。这才是重点!到这里,如果理由说服不了你,那你就不要去纠缠了。至少,你已经理清了View
与Window
之间的关系了,这就够了!
3 Activity
3.1 Activity基本理解
对于开发人员来说,一个Activity
就“相当于”一个界面(通过setContentView
指定具体的View
)。我们可以直接在Activity里处理事件,如onKeyEvent
,onTouchEvent
等。 并可以通过Activity
维护应用程序的生命周期。
3.2 Activity有存在的必要吗?
同样,我们还是以是否存在这个问题为切入点,去理清
Activity
与Window
关系。
前面我们知道,Window
已经是系统管理的窗口界面。那么为什么还需要Activity
呢?我们把Activity
所做的事情,全部封装到Window
不就好了?
其实,本质上讲,我们要显示一个窗口出来,的确可以不需要Activity
。悬浮窗口中不就是没有使用Activity
来显示一个悬浮窗吗?既然如此,Window
(以及View
)能处理点击事件以及封装各种逻辑,那为啥还需要Activity呢?
个人理解:
Android
中的应用中,里面对各个窗口的管理相当复杂(任务栈、状态等等),Android
系统当然可以不用Activity
,让用户自己直接操作Window
来开发自己的应用。但是如果让用户自己去管理这些Window
,先不说工作量,光让用户自己去实现任务栈这点,有几个人能写的出来。为了让大家能简单、快速的开发应用,Android
通过定义Activity,让Activity
帮我们管理好,我们只需简单的去重写几个回调函数,无需直接与Window
对象接触。各种事件也只需重写Activity
里面的回调即可。无需关注其他细节,默认都帮我们写好了,针对需要定制的部分我们重写(设计模式为:模板方法模式)