PolicyManager工廠模式與動態加載
Android FrameWork——PolicyManager
在學習Android跟蹤setContentView執行過程代碼的時遇到:
Attach(){
//着實不清楚PolicyManager到底如何創建的,哪一個對象。
mWindow = PolicyManager.makeNewWindow(this);
}
其中用到Class.forName動態加載,Java是最近才學的還真不曉得有這樣的用法;
一 類之間關系
於是就了解一下PolicyManager以及相關類實現方式;
首先看一下各個類之間的UML圖:
PolicyManager:提供了靜態類方法接口,用於創建Window,LayoutInflate,
WindowManagerPolicy類實例;屬於工廠方法;
IPolicy:提供抽象Policy創建產品接口;
Policy:具體IPolicy,實現創建產品接口;
二 代碼分析
1 IPolicy
/* The implementation of this interface must be called Policy and contained * within the com.android.internal.policy.impl package */
public interface IPolicy { public Window makeNewWindow(Context context); public LayoutInflater makeNewLayoutInflater(Context context); public WindowManagerPolicy makeNewWindowManager(); }
2 Policy
public class Policy implements IPolicy { private static final String TAG = "PhonePolicy";
//提供需要預先加載的 類
private static final String[] preload_classes = { "com.android.internal.policy.impl.PhoneLayoutInflater", "com.android.internal.policy.impl.PhoneWindow", "com.android.internal.policy.impl.PhoneWindow$1", "com.android.internal.policy.impl.PhoneWindow$ContextMenuCallback", "com.android.internal.policy.impl.PhoneWindow$DecorView", "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState", "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState", };
//靜態模塊
static { // For performance reasons, preload some policy specific classes when // the policy gets loaded.
for (String s : preload_classes) { try { //動態加載指定的類 Class.forName(s); } catch (ClassNotFoundException ex) { Log.e(TAG, "Could not preload class for phone policy: " + s); } } }
//創建具體對象的接口
public PhoneWindow makeNewWindow(Context context) { return new PhoneWindow(context); } public PhoneLayoutInflater makeNewLayoutInflater(Context context) { return new PhoneLayoutInflater(context); } public PhoneWindowManager makeNewWindowManager() { return new PhoneWindowManager(); } }
3 PolicyManager
//訪問類的靜態成員的時候 會加載該類
public final class PolicyManager { private static final String POLICY_IMPL_CLASS_NAME =
"com.android.internal.policy.impl.Policy";
private static final IPolicy sPolicy; //加載該類時,所有靜態成員均被會加載
static { try { //動態加載創建類實例 Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME); //創建了sPolicy指向的實例 sPolicy = (IPolicy)policyClass.newInstance(); } catch (ClassNotFoundException ex) {} } //構造函數私有類型,不能創建該類實例
private PolicyManager() {} // The static methods to spawn new policy-specific objects
public static Window makeNewWindow(Context context) { return sPolicy.makeNewWindow(context); } public static LayoutInflater makeNewLayoutInflater(Context context) { return sPolicy.makeNewLayoutInflater(context); } public static WindowManagerPolicy makeNewWindowManager() { return sPolicy.makeNewWindowManager(); } }
這里要注意的就是:動態加載Class.forName:
Class.forName()返回一個類;
String str = 用戶輸入的字符串
Class classType = Class.forName(str); //返回一個類
classType.newInstance(); //創建一個classType 類型的對象
在上述代碼中:
Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME); //加載Policy類
sPolicy = (IPolicy)policyClass.newInstance(); //創建Policy對象 給IPolicy類型sPolicy引用;
這樣動態加載加上使用工廠方法:降低耦合,提高代碼的靈活性和擴展性;