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動態解析載入流程原理分析? 第一步:主程式載入外掛程式 第二步:主程式啟動外掛流程分析