Android源码抽象工厂---IPolicy
来源:互联网 发布:mmap软件免费下载 编辑:程序博客网 时间:2024/06/06 07:04
抽象工厂应用是很广的,在Android源码中,这个IPolicy就是一个简单的抽象工厂模式。下面分析一下IPolicy及其实现,以及创建的相关对象(源码基于5.0.0)。
抽象工厂
意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
UML类图
通过继承抽象工厂,可以产生不同的产品系列
代码示例
abstract class AbsFactory{ public abstract AbsProductA createProduct1(); public abstract AbsProdcutB createProduct2(); } abstract class AbsProductA{ } abstract class AbsProductB{ } class ProductA1 extends AbsProductA{ } class ProductB1 extends AbsProductB{ public void interactWithProductA(AbsProductA product){ //与ProductA关联 } } class ConcreteFactory1 extends AbsFactory{ private static ConcreteFactory instance = new ConcreteFactory(); public ConcreteFactory getInstance(){ return instance; } public AbsProductA createProductA(){ return new ProductA1(); } public AbsProdcutB createProductB(){ return new ProductB1(); } } public static void main(String[] args){ ConcreteFactory instance = ConcreteFactory. AbsProductA product1 = instance.createProductA(); AbsProductB product2 = instance.createProductB(); product2.interactWithProductA(product1); }
抽象工厂就是创建一系列相互关联的对象,这样每一个抽象工厂的具体实现创建的对象都是相互关联的,而且可以是不同的产品系列,相当于从上层就设计好了一套产品规范。这里只是简单介绍了一下抽象工厂。如果想很好的理解可以参考设计模式:可复用面向对象软件的基础关于抽象工厂的介绍。下面介绍IPolicy。
IPolicy
IPolicy在com.android.internal.policy包下面。它是关于Android窗口,窗口管理,布局加载,以及事件回退Handler这一系列窗口相关产品的抽象工厂。先看IPolicy的UML类图。
UML图
IPolicy是产生窗口屏幕相关对象的抽象接口,在Android手机源码中,com.android.internal.policy.impl.Policy是它的唯一一个实现,按照源码中的注释所说的,是Policy是IPolicy的一个简单实现,用来生成对象集合。Policy创建一系列的Phone的窗口相关对象:PhoneWindow,PhoneLayoutInflater,PhoneWindowManager,PhoneFallbackEventHandler。从UML图就可以看出,IPolicy算是一个典型的抽象工厂,只不过在源码中只有一个具体的工厂实现。
另外Policy的实现还有一点特殊的地方,它使用static域将他需要创建的对象都预先load出来,也就是说当虚拟机加载Policy类的时候,就会加载它创建的对象的class。
相关对象介绍
下面分别介绍IPolicy创建的每个对象
PolicyManager
PolicyManager相当于是这个抽象工厂的客户端,它只有静态方法,他它的静态方法跟IPolicy的接口是相对应的。它内部包含了一个Policy对象,相当于是Policy的一个代理,对应的创建操作都会交给Policy去创建,比如说makeNewWindow方法的实现:
// The static methods to spawn new policy-specific objectspublic static Window makeNewWindow(Context context) { return sPolicy.makeNewWindow(context);}
Window与PhoneWindow
Window是Android中的窗口,每个Activity都会对应着一个Window,在Activity的attach方法中,就有Window的创建代码:
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, IVoiceInteractor voiceInteractor) { attachBaseContext(context); mFragments.attachActivity(this, mContainer, null); mWindow = PolicyManager.makeNewWindow(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); ...
attach方法是将Context,application等赋值给Activity,在Activiy启动的过程会调用。我们弹出的对话框(Dialog),里面也是有一个Window的。另外与Activity对应的还有启动窗口(Starting Window)。一个Window还可以有子Window。另外Android中还有一些其他的窗口还有输入法窗口,状态栏窗口,壁纸窗口。
窗口有一个专门的窗口管理服务WindowManagerService,在WindowManagerService中与每个Activity对应的为AppWindowToken,而AppWindowToken描述的是一组窗口(一组WindowState),对应于Activity中Context的各种窗口。
而手机中, Window的具体实现是PhoneWindow。PhoneWindow是对应着Android手机的Window实现。PhoneWindow里面包含了DecorView, DecorView包含了标题栏以及具体View(由setContentView设置)。它们之间的关系如下:
而真正直接关联Window与View的是WindowManager,由Window.setWindowManager设置。每个Window都会对应一个WindowManager。通过WindowManager的addView,updateViewLayout,removeView来添加,更新,移除Window中的View。
通过context.getSystemService(Context.WINDOW_SERVICE)可以获得WindowManager,这个就是Activity的mWindow的WindowManager,而WindowManager的具体实现是WindowManagerImpl,而WindowManagerImpl又会将Window的相关操作(addView, removeView)交给WindowManagerGlobal来实现。WindowManagerGlobal是一个单例模式,里面包含了一个ViewRootImpl列表(ArrayList),一个View列表, 一个WindowManager.LayoutParams列表,三个链表相互对应,表示一个View对应的LayoutParams和ViewRoot。WindowManagerGlobal获取了WindowManagerService的Binder接口IWindowManager。ViewRootImpl通过WindowManagerGlobal的IWindowManager获取WindowSession(Binder的Proxy),将ViewRootImpl的W(Binder对象)传给WindowManagerService,来与WindowManagerService相互通信。他们之间的UML图如下:
WindowManagerPolicy,PhoneWindowManager
这个WindowManagerPolicy不同于Window中介绍的WindownManager,Window中介绍的WindowManager是属于Window与View交互的管理,而WindowManagerPolicy则是更多地倾向于对Window屏幕的管理,比如说启动窗口就是由它创建的。也包括一个具体的屏幕管理,比如说获取屏幕显示的大小,屏幕旋转,屏幕设置等等。PhoneWindowManager是WindowManagerPolicy在手机规格下的实现。WindowManagerPolicy还有一个内部静态类WindowManagerPolicy.WindowState,它是由WindowManagerService管理的,从一个窗口开始添加就存在,到窗口移除就删除,是一个窗口的状态接口,可以获得当前窗口所属的进程,包名,当前的Frame
LayoutInflater,PhoneLayoutInflater
LayoutInflater应该都比较熟悉,它是Android中用于XML布局加载的类,它是一个抽象类,PhoneLayoutInflater是它在Android手机上面的实现。PhoneLayoutInflater中主要是实现了onCreateView方法和cloneInContext方法。
FallbackEventHandler,PhoneFallbackEventHandler
这个使用来处理按键的接口,按键事件的处理会有三个部分view树、软键盘系统、FallbackEventHandler。FallbackEventHandler是优先级最低的处理部分。只有前面两个都不处理,FallbackEventHandler才会处理,它是针对所有Window的,像声音按键就是在这里最后处理的。
IPolicy抽象工厂的设计分析
如果只看IPolicy,PolicyManager,Policy的UML,你会发现其实这三个部分也像是一个策略模式的UML图。这部分里面本身也可以说是一种策略,一种创建的策略。但把IPolicy作为抽象工厂理解会更为合适,它负责生成一系列相关产品,却不用管产品的具体实现。
首先说说这四个产品之间的关系,Window是表示窗口,抽象的窗口管理,而WindowManagerPolicy是关于窗口屏幕的管理策略,LayoutInflater是XML解析器,将XML解析为Window中具体元素View,最后FallbackEventHandler是回退事件Handler,事件会作用在窗口上面。这四个产品在不同的产品簇的具体表现会是不一样的,但是他们又有相互之间的关联。用一个统一的创建接口,在使用这些接口的时候会更加方便。
就拿Phone的这四种产品实现来说,Phone的Window,以及WindowManagerPolicy自然是不同的,另外LayoutInflater也会有所不同,比如XML的View可能限制不一样,在PhoneLayoutInflater中会从包名前缀为”android.widget.”,”android.webkit.”,”android.app.”这三个来创建View。另外如果产品簇是TV的话,FallbackEventHandler处理可能是直接回退到上一个台,而Phone的话会是返回上一个操作。
用四个工厂方法实现
其实四种不同的产品(Window,WindowManagerPolicy,LayoutInflater,是XML解析器,将XML解析为Window中具体元素View,最后FallbackEventHandler),如果用四个工厂方法也肯定是可以的,但是会缺乏将本来应该有相互关联的产品拆分开了,抽象工厂一定程度上提高了它们之间的内聚。
扩展优势分析
假如除了Phone外,又突然有了一种新的产品簇(比如说TV,智能手表,我暂时并没有调查这两种的实现方式),那么只需要创建一个对应Policy,以及对应的产品系列,然后将PolicyManager的IPolicy指向新产品簇的Policy就好了。
- Android源码抽象工厂---IPolicy
- Android源码分析之抽象工厂模式
- android 设计模式-抽象工厂
- 《Android源码设计模式》读书笔记 (6) 第6章 抽象工厂模式
- 《Android源码设计模式解析与实战》读书笔记(六)——抽象工厂模式
- 《GOF设计模式》—抽象工厂(Abstract Factory)—Delphi源码示例:抽象工厂接口
- android设计模式之抽象工厂模式
- Android开发中抽象工厂模式
- Android中的设计模式-抽象工厂模式
- 抽象工厂模式在android中使用
- Android 设计模式 笔记 - 抽象工厂模式
- Android设计模式-抽象工厂模式
- Android的设计模式-抽象工厂模式
- Android设计模式---工厂方法模式和抽象工厂模式
- 简单工厂-工厂方法-抽象工厂对比,给出理解思路和Java参考案例源码
- 抽象工厂
- 抽象工厂
- 抽象工厂
- 移动屏幕旋转解决方法
- 多线程编程API简介 下
- Eclipse:An internal error occurred during: "Build Project". GC overhead limit exceeded
- 建表参数(pctfree,IniTrans,maxtrans)含义
- 提示:Failure [INSTALL_FAILED_ALREADY_EXISTS]
- Android源码抽象工厂---IPolicy
- 调试web service的问题:“无法自动进入并单步执行服务器。无法确定停止位置。请验证是否已加载符号。未找到符号:……”
- cocos studio 3.10点击在windows平台运行报错 在windows平台运行 返回值1
- 自己实现String类
- 二分图的最大匹配、完美匹配和匈牙利算法
- 大众点评订单分库分表实践之路
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
- [django]入门教程3:模板语法及使用
- 笔记sql语句