当前位置:操作系统 > 安卓/Android >>

Android应用程序窗口(Activity)实现框架简要介绍和学习计划

   前面我们学习了SurfaceFlinger服务的实现原理。有了这个基础之后,从本文开始,我们就可以分析Android系统在Java层的UI实现了。我们知道,在Android应用程序的四大组件中,只有Activity组件与UI相关,它描述的是应用程序窗口,因此,我们就通过它的UI实现来分析Android系统在Java层的UI实现。本文主要是对Activity组件的UI实现作简要介绍以及制定学习计划。

        Activity组件的UI实现需要与WindowManagerService服务和SurfaceFlinger服务进行交互。从前面Android应用程序键盘(Keyboard)消息处理机制分析一文可以知道,Activity组件在启动完成后,会通过一个类型为Session的Binder对象来请求WindowManagerService为它创建一个类型为WindowState的对象,用来描述它的窗口状态。此外,从Android应用程序与SurfaceFlinger服务的关系概述和学习计划这一系列的文章又可以知道,Android应用程序会通过一个类型为Client的Binder对象来请求SurfaceFlinger服务为它创建一个类型为Layer的对象,用来描述它的窗口数据。

        从Android应用程序请求SurfaceFlinger服务创建Surface的过程分析一文又可以知道,SurfaceFlinger服务为Android应用程序创建一个类型为Layer的对象之后,会返回一个类型为SurfaceLayer的Binder对象给Android应用程序,这样Android应用程序就可以通过这个Binder对象来请求SurfaceFlinger服务来分配图形缓冲区。

        综合上述信息,我们就可以得到Activity组件与WindowManagerService服务和SurfaceFlinger服务的交互模型,如图1所示:

 

图1 Activity组件与WindowManagerService服务和SurfaceFlinger服务的交互模型

        事实上,用来关联Activity组件和Layer对象的SurfaceLayer对象并不是由Android应用程序请求SurfaceFlinger服务来创建的,而是由WindowManagerService服务请求SurfaceFlinger服务来创建的。WindowManagerService服务得到这个SurfaceLayer对象之后,再将它的一个代理对象返回给在Android应用程序这一侧的Activity组件。这样,Activity组件和WindowManagerService服务就可以通过同一个SurfaceLayer对象来操作在SurfaceFlinger服务这一侧的Layer对象,而操作Layer对象的目的就是为了修改Activity组件的UI。

        在前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划和Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划这两个系列的文章中,我们已经分析在SurfaceFlinger服务这一侧的Layer类和SurfaceLayer类的实现了。在现在的这一系列文章中,我们主要分析在Android应用程序这一侧的Activity组件与UI相关的类的实现,以及在WindowManagerService服务这一侧的WindowState类的实现。

        我们首先看Activity组件的实现,如图2所示:

 

图2 Activity组件的类关系图

        Activity类是从ContextThemeWrapper类继承下来的,而ContextThemeWrapper类又是从ContextWrapper类继承下来的,最后ContextWrapper类又继承了Context类。

        从前面Android应用程序启动过程源代码分析一文可以知道,Activity组件在启动的过程中,系统会为它创建一个ContextImpl对象,用来描述它的运行上下文环境。这个ContextImpl对象首先是通过调用Acitivity类的成员函数attach传递到Acticity组件内部,接着再依次通过调用父类ContextThemeWrapper和ContextWrapper的成员函数attachBaseContext来分别保存在它们的成员变量mBase中。因此,ContextThemeWrapper和ContextWrapper类的成员变量mBase指向的实际上是一个ContextImpl对象。

       从前面Android应用程序启动过程源代码分析一文还可以知道,系统为一个正在启动的Activity组件创建了一个ContextImpl对象之后,还会调用这个ContextImpl对象的成员函数setOuterContext来将正在启动的Activity组件保存在其成员变量mOuterContext中。这样,一个Activity组件就可以通过其父类ContextThemeWrapper或者ContextWrapper的成员变量mBase来访问用来描述它的运行上下文环境的一个ContextImpl对象,同时,一个ContextImpl对象也可以通过它的成员变量mOuterContext来访问它的宿主Activity组件。

      Activity类还有另外一个类型为WindowManager的成员变量mWindowManager,它实际上指向的一个LocalWindowManager对象。LocalWindowManager类是用来管理应用程序窗口的,例如,用来维护应用程序窗口内部的视图(View)。LocalWindowManager类有一个类型为WindowManager的成员变量mWindowManager,它实际上指向的是一个WindowManagerImpl对象。系统通过调用WindowManagerImpl类的静态成员函数getDefault来获得一个WindowManagerImpl对象,然后保存在LocalWindowManager类的成员变量mWindowManager中。这样,LocalWindowManager类就可以通过WindowManagerImpl类来真正实现管理应用程序窗口的功能。

      从上面的分析中,我们还看不出的一个Activity组件的窗口是如何描述的。为了弄清楚这个问题,我们继续分析Activity类的另外一个成员变量mWindow,如图3所示:

 

图3 Window类的实现

        Activity类的成员变量mWindow的类型为Window,它用来描述一个应用程序窗口。这样,通过这个成员变量,每一个Activity组件就都会有一个对应的Window对象,即一个对应的应用程序窗口。

        Window类有一个类型为Context的成员变量mContext。这个成员变量指向的是一个ContextImpl对象。当系统为一个Activity组件创建一个对应的Window对象时,就会将用来描述这个Activity组件的运行上下文环境的一个ContextImpl对象保存在对应的Window对象的成员变量mContext。这样,一个Window对象就可以通过它的成员变量mContext来访问它所描述的Activity组件的运行上下文环境。

        Window类还有一个类型为Window.Callback的成员变量mCallback。这个成员变量指向的是一个Activity对象,因为Activity类是实现了Window.Callback接口的。当系统为一个Activity组件创建一个对应的Window对象时,就会将这个Activity组件所实现的Window.Callback接口通过Window类的成员函数setCallback保存在对应的Window对象的成员变量mCallback。这样,一个Window对象就可以通过它的成员变量mCallback来将一些事件交给与它所对应的Activity组件来处理,例如,将接收的键盘事件交给对应的Activity组件来处理。

        最后,Window类还有一个类型为WindowManager的成员变量mWindowManager。这个成员变量指向的是一个LocalWindowManager对象。前面提到,Activity组件的成员变量mWindowManager指向的也是一个LocalWindowManager对象。系统在启动一个Activity组件的过程中,会通过Window类的成员函数setWindowManager来将保存在它的成员变量mWindowManager中的一个LocalWindowManager对象也保存在对应的Window对象的成员变量mWindowManager。这样,一个Activity组件以及它所对应的Window对象就可以使用同一个LocalWindowManager对象来管理它们所描述的UI了。

       事实上,Activity类的成员变量mWindow指向的并不是一个Window对象,而是一个PhoneWindow对象。也就是说,一个Activity组件的UI是使用一个PhoneWindow对象来描述的。

       Activity类的成员变量mWindow所指向的一个PhoneWindow对象是通过调用PolicyManager类的静态成员函数makeNewWindow来创建的。PolicyManager类的实现如图4所示:

 

图4 PolicyManager类的实现

        PolicyManager类有一个类型为IPolicy的静态成员变量sPolicy,它实际指向的是一个Policy对象。Policy类实现了IPolicy接口的成员函数makeNewWindow,而PolicyManager类就是通过这个成员函数来为一个Activity组件创建一个PhoneWindow对象的。

       PhoneWindow类继承了Window类,因此,它的对象可以保存Activity类的成员变量mWindow中。PhoneWindow类的实现如图5所示:

 

图5 PhoneWindow类的实现

        PhoneWindow类有两个重要的成员变量mDecor和mContentParent,它们的类型分别DecorView和ViewGroup。其中,成员变量mDecor是用描述自己的窗口视图,而成员变量mContentParent用来描述父窗口视图。

        DecorView类继承了FrameLayout类,而FrameLayout类又继承了ViewGroup类,最后ViewGroup类又继承了View类。View类有一个成员函数draw,它是用来绘制应用程序窗口的UI的。DecorView类、FrameLayout类和ViewGroup类都重写了父类的成员函数draw,这样,它们就都可以定制自己的UI。

&nbs

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,