legalAccessException
| InstantiationException
| NoSuchMethodException
| InvocationTargetException e) {
e.printStackTrace();
}
return pluginApk;
}
private PackageInfo queryPackageInfo(String apkPath) {
PackageInfo packageInfo = mContext.getPackageManager().getPackageArchiveInfo(apkPath,
PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
if (packageInfo == null) {
return null;
}
return packageInfo;
}
private DexClassLoader createDexClassLoader(String apkPath) {
File dexOutputDir = mContext.getDir("dex", Context.MODE_PRIVATE);
DexClassLoader loader = new DexClassLoader(apkPath, dexOutputDir.getAbsolutePath(),
null, mContext.getClassLoader());
return loader;
}
public void startActivity(Intent intent) {
Intent pluginIntent = new Intent(mContext, ProxyActivity.class);
Bundle extra = intent.getExtras();
// complicate if statement
if (extra == null || !extra.containsKey(Constants.PLUGIN_CLASS_NAME) && !extra.containsKey(Constants.PACKAGE_NAME)) {
try {
throw new IllegalAccessException("lack class of plugin and package name");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
pluginIntent.putExtras(intent);
pluginIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(pluginIntent);
}
}
PluginApk
表示一个Apk文件:
public class PluginApk {
public PackageInfo packageInfo;
public DexClassLoader classLoader;
public Resources pluginRes;
public PluginApk(Resources pluginRes) {
this.pluginRes = pluginRes;
}
}
所有插件Activity都要继承一个父类PluginActivity
:
public abstract class PluginActivity extends Activity implements Pluginable, Attachable<Activity> {
public final static String TAG = PluginActivity.class.getSimpleName();
protected Activity mProxyActivity;
private Resources mResources;
PluginApk mPluginApk;
@Override
public void attach(Activity proxy, PluginApk apk) {
mProxyActivity = proxy;
mPluginApk = apk;
mResources = apk.pluginRes;
}
@Override
public void setContentView(int layoutResID) {
mProxyActivity.setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
mProxyActivity.setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
mProxyActivity.setContentView(view, params);
}
@Override
public View findViewById(int id) {
return mProxyActivity.findViewById(id);
}
@Override
public Resources getResources() {
return mResources;
}
@Override
public WindowManager getWindowManager() {
return mProxyActivity.getWindowManager();
}
@Override
public ClassLoader getClassLoader() {
return mProxyActivity.getClassLoader();
}
@Override
public Context getApplicationContext() {
return mProxyActivity.getApplicationContext();
}
@Override
public MenuInflater getMenuInflater() {
return mProxyActivity.getMenuInflater();
}
@Override
public Window getWindow() {
return mProxyActivity.getWindow();
}
@Override
public Intent getIntent() {
return mProxyActivity.getIntent();
}
@Override
public LayoutInflater getLayoutInflater() {
return mProxyActivity.getLayoutInflater();
}
@Override
public String getPackageName() {
return mPluginApk.packageInfo.packageName;
}
@Override
public void onCreate(Bundle bundle) {
// DO NOT CALL s