privatestaticPluginManagercreateInstance(Contextcontext){try{//获取清单文件种的meta数据BundlemetaData=context.getPackageManager().getApplicationInfo(context.getPackageName(),PackageManager.GET_META_DATA).metaData;if(metaData==null){returnnewPluginManager(context);}StringfactoryClass=metaData.getString("VA_FACTORY");if(factoryClass==null){returnnewPluginManager(context);}//调用清单文件中Factory创建PluginManager类PluginManagerpluginManager=Reflector.on(factoryClass).method("create",Context.class).call(context);if(pluginManager!=null){Log.d(TAG,"Created a instance of "+pluginManager.getClass());returnpluginManager;}}catch(Exceptione){Log.w(TAG,"Created the instance error!",e);}//清单文件中没有声明 直接调用构造函数returnnewPluginManager(context);}
protectedvoidhookInstrumentationAndHandler(){try{//获取ActivityThreadActivityThreadactivityThread=ActivityThread.currentActivityThread();//获取ActivityThread的 Instrumentation 对象InstrumentationbaseInstrumentation=activityThread.getInstrumentation();//如果是在平行空间中运行,则退出if(baseInstrumentation.getClass().getName().contains("lbe")){// reject executing in paralell space, for example, lbe.System.exit(0);}//创建代理对象finalVAInstrumentationinstrumentation=createInstrumentation(baseInstrumentation);Reflector.with(activityThread).field("mInstrumentation").set(instrumentation);HandlermainHandler=Reflector.with(activityThread).method("getHandler").call();Reflector.with(mainHandler).field("mCallback").set(instrumentation);this.mInstrumentation=instrumentation;Log.d(TAG,"hookInstrumentationAndHandler succeed : "+mInstrumentation);}catch(Exceptione){Log.w(TAG,e);}}
@OverridepublicActivitynewActivity(ClassLoadercl,StringclassName,Intentintent)throwsInstantiationException,IllegalAccessException,ClassNotFoundException{try{cl.loadClass(className);Log.i(TAG,String.format("newActivity[%s]",className));}catch(ClassNotFoundExceptione){//没有找到类,说明是插件中的类ComponentNamecomponent=PluginUtil.getComponent(intent);if(component==null){returnnewActivity(mBase.newActivity(cl,className,intent));}StringtargetClassName=component.getClassName();Log.i(TAG,String.format("newActivity[%s : %s/%s]",className,component.getPackageName(),targetClassName));//获取插件LoadedPluginplugin=this.mPluginManager.getLoadedPlugin(component);if(plugin==null){// Not found then goto stub activity.booleandebuggable=false;try{Contextcontext=this.mPluginManager.getHostContext();debuggable=(context.getApplicationInfo().flags&ApplicationInfo.FLAG_DEBUGGABLE)!=0;}catch(Throwableex){}if(debuggable){thrownewActivityNotFoundException("error intent: "+intent.toURI());}Log.i(TAG,"Not found. starting the stub activity: "+StubActivity.class);returnnewActivity(mBase.newActivity(cl,StubActivity.class.getName(),intent));}Activityactivity=mBase.newActivity(plugin.getClassLoader(),targetClassName,intent);activity.setIntent(intent);// for 4.1+Reflector.QuietReflector.with(activity).field("mResources").set(plugin.getResources());returnnewActivity(activity);}returnnewActivity(mBase.newActivity(cl,className,intent));}
applyplugin:'com.didi.virtualapk.plugin'virtualApk{packageId=0x6f// the package id of Resources.targetHost='../../VirtualAPK/app'// the path of application module in host project.applyHostMapping=true//optional, default value: true.}
PluginManagerpluginManager=PluginManager.getInstance(base);Fileapk=newFile(Environment.getExternalStorageDirectory(),"Test.apk");try{pluginManager.loadPlugin(apk);Log.i(TAG,"Loaded plugin from apk: "+apk);}catch(Exceptione){e.printStackTrace();}
publicvoidloadPlugin(Fileapk)throwsException{if(null==apk){thrownewIllegalArgumentException("error : apk is null.");}if(!apk.exists()){// throw the FileNotFoundException by opening a stream.InputStreamin=newFileInputStream(apk);in.close();}//创建LoadedPluginLoadedPluginplugin=createLoadedPlugin(apk);if(null==plugin){thrownewRuntimeException("Can't load plugin which is invalid: "+apk.getAbsolutePath());}//包名为key 插件为valuethis.mPlugins.put(plugin.getPackageName(),plugin);//回调synchronized(mCallbacks){for(inti=0;i<mCallbacks.size();i++){mCallbacks.get(i).onAddedLoadedPlugin(plugin);}}}
protectedvoidinjectIntent(Intentintent){//将隐式Intent转换为显式IntentmPluginManager.getComponentsHandler().transformIntentToExplicitAsNeeded(intent);// null component is an implicitly intentif(intent.getComponent()!=null){// resolve intent with Stub Activity if neededthis.mPluginManager.getComponentsHandler().markIntentIfNeeded(intent);}}
publicvoidmarkIntentIfNeeded(Intentintent){if(intent.getComponent()==null){return;}StringtargetPackageName=intent.getComponent().getPackageName();StringtargetClassName=intent.getComponent().getClassName();// search map and return specific launchmode stub activityif(!targetPackageName.equals(mContext.getPackageName())&&mPluginManager.getLoadedPlugin(targetPackageName)!=null){intent.putExtra(Constants.KEY_IS_PLUGIN,true);intent.putExtra(Constants.KEY_TARGET_PACKAGE,targetPackageName);intent.putExtra(Constants.KEY_TARGET_ACTIVITY,targetClassName);dispatchStubActivity(intent);}}