外掛化設計二

kpioneer123發表於2018-01-18

FragmentActivity代理實現? 外掛化設計一 主要演示外掛化來發整體架構設計(代理模式 - 靜態代理)

 首先分析角色:
 目標介面:IPlugin目標介面
 目標物件:PluginFragmentActivity(繼承FragmentActivity)
 代理物件:ProxyPluginFragmentActivity(自定義的FragmentActivity)

 第一步:PluginFragmentActivity目標物件具體的功能
複製程式碼
//代理實現類
public class ProxyImpl {

	private static final String TAG = ProxyImpl.class.getSimpleName();

	private String mClass;
	private String mPackageName;

	private PluginPackageInfo mPluginPackage;
	private PluginManager mPluginManager;

	private AssetManager mAssetManager;
	private Resources mResources;
	private Theme mTheme;

	private ActivityInfo mActivityInfo;
	private Activity mProxyActivity;
	protected IPlugin mPluginActivity;
	public ClassLoader mPluginClassLoader;

	public ProxyImpl(Activity activity) {
		mProxyActivity = activity;
	}

	private void initActivityInfo() {
		PackageInfo packageInfo = mPluginPackage.packageInfo;
		if ((packageInfo.activities != null)
				&& (packageInfo.activities.length > 0)) {
			if (mClass == null) {
				mClass = packageInfo.activities[0].name;
			}

			// Finals 修復主題BUG
			int defaultTheme = packageInfo.applicationInfo.theme;
			for (ActivityInfo a : packageInfo.activities) {
				if (a.name.equals(mClass)) {
					mActivityInfo = a;
					// Finals ADD 修復主題沒有配置的時候外掛異常
					if (mActivityInfo.theme == 0) {
						if (defaultTheme != 0) {
							mActivityInfo.theme = defaultTheme;
						} else {
							if (Build.VERSION.SDK_INT >= 14) {
								mActivityInfo.theme = android.R.style.Theme_DeviceDefault;
							} else {
								mActivityInfo.theme = android.R.style.Theme;
							}
						}
					}
				}
			}

		}
	}

	private void handleActivityInfo() {
		Log.d(TAG, "handleActivityInfo, theme=" + mActivityInfo.theme);
		if (mActivityInfo.theme > 0) {
			mProxyActivity.setTheme(mActivityInfo.theme);
		}
		Theme superTheme = mProxyActivity.getTheme();
		mTheme = mResources.newTheme();
		mTheme.setTo(superTheme);
		// Finals適配三星以及部分載入XML出現異常BUG
		try {
			mTheme.applyStyle(mActivityInfo.theme, true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void onCreate(Intent intent) {
		intent.setExtrasClassLoader(PluginConfigs.sPluginClassloader);

		mPackageName = intent.getStringExtra(PluginConstants.EXTRA_PACKAGE);
		mClass = intent.getStringExtra(PluginConstants.EXTRA_CLASS);
		Log.d(TAG, "mClass=" + mClass + " mPackageName=" + mPackageName);

		mPluginManager = PluginManager.getInstance(mProxyActivity);
		mPluginPackage = mPluginManager.getPackage(mPackageName);
		mAssetManager = mPluginPackage.assetManager;
		mResources = mPluginPackage.resources;

		initActivityInfo();
		handleActivityInfo();
		launchTargetActivity();
	}

	/**
	 * 啟動外掛程式(實際上是啟動代理物件Activity)
	 */
	protected void launchTargetActivity() {
		try {
			// 載入外掛程式(說白了mClass就是PluginActivity)
			Class<?> localClass = getClassLoader().loadClass(mClass);
			Constructor<?> localConstructor = localClass
					.getConstructor(new Class[] {});
			Object instance = localConstructor.newInstance(new Object[] {});
			mPluginActivity = (IPlugin) instance;
            /**
             * 在呼叫目標物件的時候,我們的代理物件持有目標物件的引用
             */
			((IAttachable) mProxyActivity).attach(mPluginActivity,
					mPluginManager);
			Log.d(TAG, "instance = " + instance);
			// attach the proxy activity and plugin package to the
			// mPluginActivity
			// 外掛程式傳入代理物件
			mPluginActivity.attach(mProxyActivity, mPluginPackage);


            /**
             * 明確了PluginActivityon Create()  判斷當前這個Activity是主程式的Activity。還是外掛程式的Activity
             */
			Bundle bundle = new Bundle();
			bundle.putInt(PluginConstants.FROM, PluginConstants.FROM_EXTERNAL);
			mPluginActivity.onCreate(bundle);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ClassLoader getClassLoader() {
		return mPluginPackage.classLoader;
	}

	public AssetManager getAssets() {
		return mAssetManager;
	}

	public Resources getResources() {
		return mResources;
	}

	public Theme getTheme() {
		return mTheme;
	}

	public IPlugin getRemoteActivity() {
		return mPluginActivity;
	}

}
複製程式碼

Activity可以被例項化 但是系統就不會進行管理(生命週期)

第一步:PluginFragmentActivity目標物件具體的功能 第二步:ProxyPluginFragmentActivity代理物件具體功能實現

3.Apk動態解析載入流程原理分析? 第一步:主程式載入外掛程式 第二步:主程式啟動外掛流程分析

相關文章