/** * //If getComponent returns an explicit class, that is returned without any further * consideration. //If getAction is non-NULL, the activity must handle this action. //If * resolveType returns non-NULL, the activity must handle this type. //If addCategory has added * any categories, the activity must handle ALL of the categories specified. //If getPackage is * non-NULL, only activity components in that application package will be considered. * * @param intent * @return */ public static String matchPlugin(Intent intent) { Iterator<PluginDescriptor> itr = getPlugins().iterator(); while (itr.hasNext()) { PluginDescriptor plugin = itr.next(); // 如果是通过组件进行匹配的 if (intent.getComponent() != null) { if (plugin.containsName(intent.getComponent().getClassName())) { return intent.getComponent().getClassName(); } } else { // 如果是通过IntentFilter进行匹配的 String clazzName = findClassNameByIntent(intent, plugin.getActivitys()); if (clazzName == null) { clazzName = findClassNameByIntent(intent, plugin.getServices()); } if (clazzName == null) { clazzName = findClassNameByIntent(intent, plugin.getReceivers()); } if (clazzName != null) { return clazzName; } } } return null; }
private void listAll() { ViewGroup root = mList; root.removeAllViews(); // 列出所有已经安装的插件 Collection<PluginDescriptor> plugins = PluginLoader.getPlugins(); Iterator<PluginDescriptor> itr = plugins.iterator(); while (itr.hasNext()) { final PluginDescriptor pluginDescriptor = itr.next(); Button button = new Button(this); button.setPadding(10, 10, 10, 10); button.setText("插件id:" + pluginDescriptor.getPackageName() + ",点击查看"); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(PluginListActivity.this, PluginDetailActivity.class); intent.putExtra("plugin_id", pluginDescriptor.getPackageName()); startActivity(intent); } }); LayoutParams layoutParam = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); layoutParam.topMargin = 10; layoutParam.bottomMargin = 10; layoutParam.gravity = Gravity.LEFT; root.addView(button, layoutParam); } }
/** * 获取目标类型,activity or service or broadcast * * @param intent * @return */ public static int getTargetType(Intent intent) { Iterator<PluginDescriptor> itr = getPlugins().iterator(); while (itr.hasNext()) { PluginDescriptor plugin = itr.next(); // 如果是通过组件进行匹配的 if (intent.getComponent() != null) { if (plugin.containsName(intent.getComponent().getClassName())) { return plugin.getType(intent.getComponent().getClassName()); } } else { String clazzName = findClassNameByIntent(intent, plugin.getActivitys()); if (clazzName == null) { clazzName = findClassNameByIntent(intent, plugin.getServices()); } if (clazzName == null) { clazzName = findClassNameByIntent(intent, plugin.getReceivers()); } if (clazzName != null) { return plugin.getType(clazzName); } } } return PluginDescriptor.UNKOWN; }
public static boolean isInstalled(String pluginId, String pluginVersion) { PluginDescriptor pluginDescriptor = getPluginDescriptorByPluginId(pluginId); if (pluginDescriptor != null) { return pluginDescriptor.getVersion().equals(pluginVersion); } return false; }
@SuppressWarnings("rawtypes") public static Class loadPluginClassByName(String clazzName) { PluginDescriptor pluginDescriptor = getPluginDescriptorByClassName(clazzName); if (pluginDescriptor != null) { ensurePluginInited(pluginDescriptor); DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader(); try { Class pluginClazz = ((ClassLoader) pluginClassLoader).loadClass(clazzName); LogUtil.d("loadPluginClass Success for clazzName ", clazzName); return pluginClazz; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (java.lang.IllegalAccessError illegalAccessError) { illegalAccessError.printStackTrace(); throw new IllegalAccessError( "出现这个异常最大的可能是插件dex和" + "宿主dex包含了相同的class导致冲突, " + "请检查插件的编译脚本,确保排除了所有公共依赖库的jar"); } } LogUtil.e("loadPluginClass Fail for clazzName ", clazzName); return null; }
@SuppressWarnings("rawtypes") public static Class loadPluginClassByName(String clazzName) { PluginDescriptor pluginDescriptor = getPluginDescriptorByClassName(clazzName); if (pluginDescriptor != null) { ensurePluginInited(pluginDescriptor); DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader(); try { Class pluginClazz = ((ClassLoader) pluginClassLoader).loadClass(clazzName); LogUtil.d("loadPluginClass Success for clazzName ", clazzName); return pluginClazz; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (java.lang.IllegalAccessError illegalAccessError) { illegalAccessError.printStackTrace(); } } LogUtil.e("loadPluginClass Fail for clazzName ", clazzName); return null; }
/** * 根据插件中的classId加载一个插件中的class * * @param clazzId * @return */ @SuppressWarnings("rawtypes") public static Class loadPluginFragmentClassById(String clazzId) { PluginDescriptor pluginDescriptor = getPluginDescriptorByFragmenetId(clazzId); if (pluginDescriptor != null) { ensurePluginInited(pluginDescriptor); DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader(); String clazzName = pluginDescriptor.getPluginClassNameById(clazzId); if (clazzName != null) { try { Class pluginClazz = ((ClassLoader) pluginClassLoader).loadClass(clazzName); LogUtil.d("loadPluginClass for clazzId", clazzId, "clazzName", clazzName, "success"); return pluginClazz; } catch (ClassNotFoundException e) { e.printStackTrace(); } } } LogUtil.e("loadPluginClass for clazzId", clazzId, "fail"); return null; }
/** * 构造插件信息 * * @param */ static void ensurePluginInited(PluginDescriptor pluginDescriptor) { if (pluginDescriptor != null) { DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader(); if (pluginClassLoader == null) { LogUtil.d("正在初始化插件Resources, DexClassLoader, Context, Application "); LogUtil.d("是否为独立插件", pluginDescriptor.isStandalone()); Resources pluginRes = PluginCreator.createPluginResource( sApplication, pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone()); pluginClassLoader = PluginCreator.createPluginClassLoader( pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone()); Context pluginContext = PluginCreator.createPluginApplicationContext( pluginDescriptor, sApplication, pluginRes, pluginClassLoader); pluginContext.setTheme(sApplication.getApplicationContext().getApplicationInfo().theme); pluginDescriptor.setPluginContext(pluginContext); pluginDescriptor.setPluginClassLoader(pluginClassLoader); // 使用了openAtlasExtention之后就不需要Public.xml文件了 // checkPluginPublicXml(pluginDescriptor, pluginRes); callPluginApplicationOnCreate(pluginDescriptor); LogUtil.d("初始化插件" + pluginDescriptor.getPackageName() + "完成"); } } }
private static void callPluginApplicationOnCreate(PluginDescriptor pluginDescriptor) { Application application = null; if (pluginDescriptor.getPluginApplication() == null && pluginDescriptor.getPluginClassLoader() != null) { try { LogUtil.d("创建插件Application", pluginDescriptor.getApplicationName()); application = Instrumentation.newApplication( pluginDescriptor .getPluginClassLoader() .loadClass(pluginDescriptor.getApplicationName()), pluginDescriptor.getPluginContext()); pluginDescriptor.setPluginApplication(application); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } // 安装ContentProvider PluginInjector.installContentProviders( sApplication, pluginDescriptor.getProviderInfos().values()); // 执行onCreate if (application != null) { application.onCreate(); } changeListener.onPluginStarted(pluginDescriptor.getPackageName()); }
@TargetApi(Build.VERSION_CODES.GINGERBREAD) public static Drawable getLogo(PluginDescriptor pd) { PackageManager pm = PluginLoader.getApplication().getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(pd.getInstalledPath(), PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; appInfo.sourceDir = pd.getInstalledPath(); appInfo.publicSourceDir = pd.getInstalledPath(); Drawable logo = pm.getApplicationLogo(appInfo); return logo; } return null; }
private static Context newDefaultAppContext(PluginDescriptor pluginDescriptor) { Context newContext = null; if (pluginDescriptor != null && pluginDescriptor.getPluginContext() != null) { Context originContext = pluginDescriptor.getPluginContext(); newContext = PluginCreator.createPluginContext( ((PluginContextTheme) originContext).getPluginDescriptor(), sApplication, originContext.getResources(), (DexClassLoader) originContext.getClassLoader()); newContext.setTheme(pluginDescriptor.getApplicationTheme()); } return newContext; }
public static Context getDefaultPluginContext(String pluginId) { Context pluginContext = null; PluginDescriptor pluginDescriptor = getPluginDescriptorByPluginId(pluginId); if (pluginDescriptor != null) { pluginContext = pluginDescriptor.getPluginContext(); } else { LogUtil.e("PluginDescriptor Not Found for ", pluginId); } if (pluginContext == null) { LogUtil.e("Context Not Found for ", pluginId); } return pluginContext; }
/** * 获取当前class所在插件的Context 每个插件只有1个DefaultContext, 是当前插件中所有class公用的Context * * @param clazz * @return */ public static Context getDefaultPluginContext(@SuppressWarnings("rawtypes") Class clazz) { Context pluginContext = null; PluginDescriptor pluginDescriptor = getPluginDescriptorByClassName(clazz.getName()); if (pluginDescriptor != null) { pluginContext = pluginDescriptor.getPluginContext(); } else { LogUtil.e("PluginDescriptor Not Found for ", clazz.getName()); } if (pluginContext == null) { LogUtil.e("Context Not Found for ", clazz.getName()); } return pluginContext; }
public static String getLabel(PluginDescriptor pd) { PackageManager pm = PluginLoader.getApplication().getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(pd.getInstalledPath(), PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; appInfo.sourceDir = pd.getInstalledPath(); appInfo.publicSourceDir = pd.getInstalledPath(); String label = null; try { if (!isMainResId(appInfo.labelRes)) { label = pm.getApplicationLabel(appInfo).toString(); } } catch (Resources.NotFoundException e) { } if (label == null || label.equals(pd.getPackageName())) { // 可能设置的lable是来自宿主的资源 if (pd.getDescription() != null) { int id = ResourceUtil.getResourceId(pd.getDescription()); if (id != 0) { // 再宿主中查一次 try { label = PluginLoader.getApplication().getResources().getString(id); } catch (Resources.NotFoundException e) { } } } } if (label != null) { return label; } } return pd.getDescription(); }
/** * for eclipse & ant with public.xml * * <p>unused * * @param pluginDescriptor * @param res * @return */ private static boolean checkPluginPublicXml(PluginDescriptor pluginDescriptor, Resources res) { // "plugin_layout_1"资源id时由public.xml配置的 // 如果没有检测到这个资源,说明编译时没有引入public.xml, // 这里直接抛个异常出去。 // 不同的系统版本获取id的方式不同, // 三星4.x等系统适用 int publicStub = res.getIdentifier("plugin_layout_1", "layout", pluginDescriptor.getPackageName()); if (publicStub == 0) { // 小米5.x等系统适用 publicStub = res.getIdentifier("plugin_layout_1", "layout", sApplication.getPackageName()); } if (publicStub == 0) { try { // 如果以上两种方式都检测失败,最后尝试通过反射检测 Class layoutClass = ((ClassLoader) pluginDescriptor.getPluginClassLoader()) .loadClass(pluginDescriptor.getPackageName() + ".R$layout"); Integer layouId = (Integer) RefInvoker.getFieldObject(null, layoutClass, "plugin_layout_1"); if (layouId != null) { publicStub = layouId; } } catch (ClassNotFoundException e) { e.printStackTrace(); } } if (publicStub == 0) { throw new IllegalStateException( "\n插件工程没有使用public.xml给资源id分组!!!\n" + "插件工程没有使用public.xml给资源id分组!!!\n" + "插件工程没有使用public.xml给资源id分组!!!\n" + "重要的事情讲三遍!!!"); } return true; }
public static ArrayList<String> matchPlugin(Intent intent, int type) { ArrayList<String> result = null; String packageName = intent.getPackage(); if (packageName == null && intent.getComponent() != null) { packageName = intent.getComponent().getPackageName(); } if (packageName != null && !packageName.equals(PluginLoader.getApplicatoin().getPackageName())) { PluginDescriptor dp = getPluginDescriptorByPluginId(packageName); if (dp != null) { List<String> list = dp.matchPlugin(intent, type); if (list != null && list.size() > 0) { if (result == null) { result = new ArrayList<>(); } result.addAll(list); } } } else { Iterator<PluginDescriptor> itr = getPlugins().iterator(); while (itr.hasNext()) { List<String> list = itr.next().matchPlugin(intent, type); if (list != null && list.size() > 0) { if (result == null) { result = new ArrayList<>(); } result.addAll(list); } if (result != null && type != PluginDescriptor.BROADCAST) { break; } } } return result; }
/** * 安装一个插件 * * @param srcPluginFile * @return */ public static synchronized int installPlugin(String srcPluginFile) { LogUtil.e("开始安装插件", srcPluginFile); if (TextUtils.isEmpty(srcPluginFile) || !new File(srcPluginFile).exists()) { return SRC_FILE_NOT_FOUND; } // 第0步,先将apk复制到宿主程序私有目录,防止在安装过程中文件被篡改 if (!srcPluginFile.startsWith(sApplication.getCacheDir().getAbsolutePath())) { String tempFilePath = sApplication.getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".apk"; if (FileUtil.copyFile(srcPluginFile, tempFilePath)) { srcPluginFile = tempFilePath; } else { LogUtil.e("复制插件文件失败", srcPluginFile, tempFilePath); return COPY_FILE_FAIL; } } // 第1步,验证插件APK签名,如果被篡改过,将获取不到证书 // sApplication.getPackageManager().getPackageArchiveInfo(srcPluginFile, // PackageManager.GET_SIGNATURES); Signature[] pluginSignatures = PackageVerifyer.collectCertificates(srcPluginFile, false); boolean isDebugable = (0 != (sApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)); if (pluginSignatures == null) { LogUtil.e("插件签名验证失败", srcPluginFile); new File(srcPluginFile).delete(); return SIGNATURES_INVALIDATE; } else if (NEED_VERIFY_CERT && !isDebugable) { // 可选步骤,验证插件APK证书是否和宿主程序证书相同。 // 证书中存放的是公钥和算法信息,而公钥和私钥是1对1的 // 公钥相同意味着是同一个作者发布的程序 Signature[] mainSignatures = null; try { PackageInfo pkgInfo = sApplication .getPackageManager() .getPackageInfo(sApplication.getPackageName(), PackageManager.GET_SIGNATURES); mainSignatures = pkgInfo.signatures; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } if (!PackageVerifyer.isSignaturesSame(mainSignatures, pluginSignatures)) { LogUtil.e("插件证书和宿主证书不一致", srcPluginFile); new File(srcPluginFile).delete(); return VERIFY_SIGNATURES_FAIL; } } // 第2步,解析Manifest,获得插件详情 PluginDescriptor pluginDescriptor = PluginManifestParser.parseManifest(srcPluginFile); if (pluginDescriptor == null || TextUtils.isEmpty(pluginDescriptor.getPackageName())) { LogUtil.e("解析插件Manifest文件失败", srcPluginFile); new File(srcPluginFile).delete(); return PARSE_MANIFEST_FAIL; } PackageInfo packageInfo = sApplication .getPackageManager() .getPackageArchiveInfo(srcPluginFile, PackageManager.GET_GIDS); if (packageInfo != null) { pluginDescriptor.setApplicationTheme(packageInfo.applicationInfo.theme); pluginDescriptor.setApplicationIcon(packageInfo.applicationInfo.icon); pluginDescriptor.setApplicationLogo(packageInfo.applicationInfo.logo); } boolean isNeedPending = false; // 第3步,检查插件是否已经存在,若存在删除旧的 PluginDescriptor oldPluginDescriptor = getPluginDescriptorByPluginId(pluginDescriptor.getPackageName()); if (oldPluginDescriptor != null) { LogUtil.e( "已安装过,安装路径为", oldPluginDescriptor.getInstalledPath(), oldPluginDescriptor.getVersion(), pluginDescriptor.getVersion()); // 检查插件是否已经加载 if (oldPluginDescriptor.getPluginContext() != null) { if (!oldPluginDescriptor.getVersion().equals(pluginDescriptor.getVersion())) { LogUtil.e("旧版插件已经加载, 且新版插件和旧版插件版本不同,进入pending状态,新版插件将在安装后进程重启再生效"); isNeedPending = true; } else { LogUtil.e("旧版插件已经加载, 且新版插件和旧版插件版本相同,拒绝安装"); new File(srcPluginFile).delete(); return FAIL_BECAUSE_HAS_LOADED; } } else { LogUtil.e("旧版插件还未加载,忽略版本,直接删除旧版,尝试安装新版"); remove(oldPluginDescriptor.getPackageName()); } } // 第4步骤,复制插件到插件目录 String destApkPath = pluginManager.genInstallPath( pluginDescriptor.getPackageName(), pluginDescriptor.getVersion()); boolean isCopySuccess = FileUtil.copyFile(srcPluginFile, destApkPath); if (!isCopySuccess) { LogUtil.e("复制插件到安装目录失败", srcPluginFile); // 删掉临时文件 new File(srcPluginFile).delete(); return COPY_FILE_FAIL; } else { // 第5步,先解压so到临时目录,再从临时目录复制到插件so目录。 在构造插件Dexclassloader的时候,会使用这个so目录作为参数 File apkParent = new File(destApkPath).getParentFile(); File tempSoDir = new File(apkParent, "temp"); Set<String> soList = FileUtil.unZipSo(srcPluginFile, tempSoDir); if (soList != null) { for (String soName : soList) { FileUtil.copySo(tempSoDir, soName, apkParent.getAbsolutePath()); } // 删掉临时文件 FileUtil.deleteAll(tempSoDir); } // 第6步 添加到已安装插件列表 pluginDescriptor.setInstalledPath(destApkPath); boolean isInstallSuccess = false; if (!isNeedPending) { isInstallSuccess = pluginManager.addOrReplace(pluginDescriptor); } else { isInstallSuccess = pluginManager.pending(pluginDescriptor); } // 删掉临时文件 new File(srcPluginFile).delete(); if (!isInstallSuccess) { LogUtil.e("安装插件失败", srcPluginFile); new File(destApkPath).delete(); return INSTALL_FAIL; } else { // 通过创建classloader来触发dexopt,但不加载 LogUtil.d("正在进行DEXOPT...", pluginDescriptor.getInstalledPath()); FileUtil.deleteAll(new File(apkParent, "dalvik-cache")); PluginCreator.createPluginClassLoader( pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone(), null); LogUtil.d("DEXOPT完毕"); if (!isNeedPending) { LocalServiceManager.registerService(pluginDescriptor); } changeListener.onPluginInstalled( pluginDescriptor.getPackageName(), pluginDescriptor.getVersion()); LogUtil.e("安装插件成功," + (isNeedPending ? " 重启进程生效" : " 立即生效"), destApkPath); return SUCCESS; } } }
/** * 安装一个插件 * * @param srcPluginFile * @return */ public static synchronized int installPlugin(String srcPluginFile) { LogUtil.d("开始安装插件", srcPluginFile); if (TextUtils.isEmpty(srcPluginFile) || !new File(srcPluginFile).exists()) { return SRC_FILE_NOT_FOUND; } // 第0步,先将apk复制到宿主程序私有目录,防止在安装过程中文件被篡改 if (!srcPluginFile.startsWith(sApplication.getCacheDir().getAbsolutePath())) { String tempFilePath = sApplication.getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".apk"; if (FileUtil.copyFile(srcPluginFile, tempFilePath)) { srcPluginFile = tempFilePath; } else { LogUtil.e("复制插件文件失败失败", srcPluginFile, tempFilePath); return COPY_FILE_FAIL; } } // 第1步,验证插件APK签名,如果被篡改过,将获取不到证书 // sApplication.getPackageManager().getPackageArchiveInfo(srcPluginFile, // PackageManager.GET_SIGNATURES); Signature[] pluginSignatures = PackageVerifyer.collectCertificates(srcPluginFile, false); boolean isDebugable = (0 != (sApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)); if (pluginSignatures == null) { LogUtil.e("插件签名验证失败", srcPluginFile); new File(srcPluginFile).delete(); return SIGNATURES_INVALIDATE; } else if (NEED_VERIFY_CERT && !isDebugable) { // 可选步骤,验证插件APK证书是否和宿主程序证书相同。 // 证书中存放的是公钥和算法信息,而公钥和私钥是1对1的 // 公钥相同意味着是同一个作者发布的程序 Signature[] mainSignatures = null; try { PackageInfo pkgInfo = sApplication .getPackageManager() .getPackageInfo(sApplication.getPackageName(), PackageManager.GET_SIGNATURES); mainSignatures = pkgInfo.signatures; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } if (!PackageVerifyer.isSignaturesSame(mainSignatures, pluginSignatures)) { LogUtil.e("插件证书和宿主证书不一致", srcPluginFile); new File(srcPluginFile).delete(); return VERIFY_SIGNATURES_FAIL; } } // 第2步,解析Manifest,获得插件详情 PluginDescriptor pluginDescriptor = ManifestParser.parseManifest(srcPluginFile); if (pluginDescriptor == null || TextUtils.isEmpty(pluginDescriptor.getPackageName())) { LogUtil.e("解析插件Manifest文件失败", srcPluginFile); new File(srcPluginFile).delete(); return PARSE_MANIFEST_FAIL; } PackageInfo packageInfo = sApplication .getPackageManager() .getPackageArchiveInfo(srcPluginFile, PackageManager.GET_GIDS); pluginDescriptor.setApplicationTheme(packageInfo.applicationInfo.theme); pluginDescriptor.setApplicationIcon(packageInfo.applicationInfo.icon); pluginDescriptor.setApplicationLogo(packageInfo.applicationInfo.logo); // 第3步,检查插件是否已经存在,若存在删除旧的 PluginDescriptor oldPluginDescriptor = getPluginDescriptorByPluginId(pluginDescriptor.getPackageName()); if (oldPluginDescriptor != null) { LogUtil.e("已安装过,先删除旧版本", pluginDescriptor.getInstalledPath()); remove(pluginDescriptor.getPackageName()); } // 第4步骤,复制插件到插件目录 String destPluginFile = pluginManager.genInstallPath( pluginDescriptor.getPackageName(), pluginDescriptor.getVersion()); boolean isCopySuccess = FileUtil.copyFile(srcPluginFile, destPluginFile); if (!isCopySuccess) { LogUtil.d("复制插件到安装目录失败", srcPluginFile); new File(srcPluginFile).delete(); return COPY_FILE_FAIL; } else { // 第5步,复制插件so到插件so目录, 在构造插件Dexclassloader的时候,会使用这个so目录作为参数 File tempDir = new File(new File(destPluginFile).getParentFile(), "temp"); Set<String> soList = FileUtil.unZipSo(srcPluginFile, tempDir); if (soList != null) { for (String soName : soList) { FileUtil.copySo( tempDir, soName, new File(destPluginFile).getParent() + File.separator + "lib"); } FileUtil.deleteAll(tempDir); } // 第6步 添加到已安装插件列表 pluginDescriptor.setInstalledPath(destPluginFile); boolean isInstallSuccess = pluginManager.addOrReplace(pluginDescriptor); new File(srcPluginFile).delete(); if (!isInstallSuccess) { LogUtil.d("安装插件失败", srcPluginFile); return INSTALL_FAIL; } else { changeListener.onPluginInstalled( pluginDescriptor.getPackageName(), pluginDescriptor.getVersion()); LogUtil.d("安装插件成功", destPluginFile); return SUCCESS; } } }
/** * 构造插件信息 * * @param */ static void ensurePluginInited(PluginDescriptor pluginDescriptor) { if (pluginDescriptor != null) { DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader(); if (pluginClassLoader == null) { LogUtil.e( "正在初始化插件" + pluginDescriptor.getPackageName() + "Resources, DexClassLoader, Context, Application"); LogUtil.d("是否为独立插件", pluginDescriptor.isStandalone()); Resources pluginRes = PluginCreator.createPluginResource(sApplication, pluginDescriptor); pluginClassLoader = PluginCreator.createPluginClassLoader( pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone(), pluginDescriptor.getDependencies()); Context pluginContext = PluginCreator.createPluginContext( pluginDescriptor, sApplication, pluginRes, pluginClassLoader); // 插件Context默认主题设置为插件application主题 pluginContext.setTheme(pluginDescriptor.getApplicationTheme()); pluginDescriptor.setPluginContext(pluginContext); pluginDescriptor.setPluginClassLoader(pluginClassLoader); try { ActivityThread.installPackageInfo(getApplicatoin(), pluginDescriptor.getPackageName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } callPluginApplicationOnCreate(pluginDescriptor); LogUtil.e("初始化插件" + pluginDescriptor.getPackageName() + "完成"); } } }