Skip to content

Commit feebc96

Browse files
committed
1、增加对插件是否使用了public.xml的检查步骤,失败时终止插件
2、当插件本身时可以独立运行的apk时,隔离插件class和宿主程序class(但是仍然合并res,由于增加了public.xml的检查,不用担心id冲突的问题) 3、更新HelloWork插件demo
1 parent b9c60c0 commit feebc96

File tree

6 files changed

+62
-18
lines changed

6 files changed

+62
-18
lines changed

PluginCore/src/com/plugin/core/PluginCreator.java

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,14 @@ private PluginCreator() {
2626
* @return
2727
*/
2828
public static DexClassLoader createPluginClassLoader(String absolutePluginApkPath, boolean isStandalone) {
29-
return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(), null,
30-
PluginLoader.class.getClassLoader());
29+
if (!isStandalone) {
30+
return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(), null,
31+
PluginLoader.class.getClassLoader());
32+
} else {
33+
return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(), null,
34+
PluginLoader.class.getClassLoader().getParent());
35+
}
36+
3137
}
3238

3339
/**
@@ -44,32 +50,50 @@ public static Resources createPluginResource(Application application, String abs
4450
AssetManager assetMgr = AssetManager.class.newInstance();
4551
Method addAssetPaths = AssetManager.class.getDeclaredMethod("addAssetPaths", String[].class);
4652

47-
String[] assetPaths = new String[2];
48-
49-
//不可更改顺序否则不能兼容4.x
50-
assetPaths[0] = application.getApplicationInfo().sourceDir;
51-
assetPaths[1] = absolutePluginApkPath;
52-
53-
if ("vivo".equalsIgnoreCase(Build.BRAND) || "oppo".equalsIgnoreCase(Build.BRAND)) {
54-
//但是!!!如是OPPO或者vivo4.x系统的话 ,要吧这个顺序反过来,否则在混合模式下会找不到资源
55-
assetPaths[0] = absolutePluginApkPath;
56-
assetPaths[1] = application.getApplicationInfo().sourceDir;
57-
}
58-
53+
//如果是独立插件的话,本来是可以不合并主程序资源的。
54+
//但是由于插件运行时可能会通过getActivityInfo等
55+
//会拿到到PluginStubActivity的ActivityInfo以及ApplicationInfo
56+
//这两个info里面有部分资源id是在宿主程序的Manifest中配置的,比如logo和icon
57+
//尝试通过插件Context获取这些资源会导致异常
58+
//所以这里强制合并资源。
59+
//强制合并资源,又需要另外一个前提条件,即id不重复。
60+
//所以不管是独立插件还是非独立插件,都需要在编译时引入public.xml文件来给资源id分组
61+
String[] assetPaths = buildAssetPath(false, application.getApplicationInfo().sourceDir, absolutePluginApkPath);
62+
5963
addAssetPaths.invoke(assetMgr, new Object[] { assetPaths });
6064

6165
Resources mainRes = application.getResources();
6266
Resources pluginRes = new Resources(assetMgr, mainRes.getDisplayMetrics(), mainRes.getConfiguration());
6367

64-
LogUtil.d("create Plugin Resource from: ", assetPaths[0], assetPaths[1]);
65-
6668
return pluginRes;
6769
} catch (Exception e) {
6870
e.printStackTrace();
6971
}
7072
return null;
7173
}
7274

75+
private static String[] buildAssetPath(boolean isStandalone, String app, String plugin) {
76+
String[] assetPaths = new String[isStandalone?1:2];
77+
78+
if (!isStandalone) {
79+
//不可更改顺序否则不能兼容4.x
80+
assetPaths[0] = app;
81+
assetPaths[1] = plugin;
82+
if ("vivo".equalsIgnoreCase(Build.BRAND) || "oppo".equalsIgnoreCase(Build.BRAND) || "Coolpad".equalsIgnoreCase(Build.BRAND)) {
83+
//但是!!!如是OPPO或者vivo4.x系统的话 ,要吧这个顺序反过来,否则在混合模式下会找不到资源
84+
assetPaths[0] = plugin;
85+
assetPaths[1] = app;
86+
}
87+
LogUtil.d("create Plugin Resource from: ", assetPaths[0], assetPaths[1]);
88+
} else {
89+
assetPaths[0] = plugin;
90+
LogUtil.d("create Plugin Resource from: ", assetPaths[0]);
91+
}
92+
93+
return assetPaths;
94+
95+
}
96+
7397
/*package*/ static Resources createPluginResourceFor5(Application application, String absolutePluginApkPath) {
7498
try {
7599
AssetManager assetMgr = AssetManager.class.newInstance();

PluginCore/src/com/plugin/core/PluginLoader.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ private static void initPlugin(PluginDescriptor pluginDescriptor) {
242242
LogUtil.d("是否为独立插件", pluginDescriptor.isStandalone());
243243

244244
Resources pluginRes = PluginCreator.createPluginResource(sApplication, pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone());
245+
246+
checkPluginPublicXml(pluginRes);
247+
245248
DexClassLoader pluginClassLoader = PluginCreator.createPluginClassLoader(pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone());
246249
Context pluginContext = PluginCreator
247250
.createPluginApplicationContext(sApplication, pluginRes, pluginClassLoader);
@@ -277,6 +280,21 @@ private static void initPlugin(PluginDescriptor pluginDescriptor) {
277280
}
278281
}
279282

283+
private static boolean checkPluginPublicXml(Resources res) {
284+
//"plugin_layout_1"资源id时由public.xml配置的
285+
//如果没有检测到这个资源,说明编译时没有引入public.xml,
286+
//这里直接抛个异常出去。
287+
int publicStub = res.getIdentifier("plugin_layout_1", "layout",
288+
sApplication.getPackageName());
289+
if (publicStub == 0) {
290+
throw new IllegalStateException("\n插件工程没有使用public.xml给资源id分组!!!\n"
291+
+ "插件工程没有使用public.xml给资源id分组!!!\n"
292+
+ "插件工程没有使用public.xml给资源id分组!!!\n"
293+
+ "重要的事情讲三遍!!!");
294+
}
295+
return true;
296+
}
297+
280298
private static synchronized boolean saveInstalledPlugins(Hashtable<String, PluginDescriptor> installedPlugins) {
281299

282300
ObjectOutputStream objectOutputStream = null;

PluginMain/assets/HelloWork.apk

1.14 KB
Binary file not shown.

PluginMain/src/com/example/pluginmain/PluginDebugHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import android.text.TextUtils;
1212
import android.util.Log;
1313

14-
import com.plugin.core.PluginLoader;
1514
import com.plugin.core.PluginDispatcher;
15+
import com.plugin.core.PluginLoader;
1616

1717
/**
1818
* 监听插件apk的安装广播, 并安装插件到宿主程序。

PluginMain/src/com/example/pluginmain/PluginDetailActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import android.widget.Toast;
1818

1919
import com.plugin.content.PluginDescriptor;
20-
import com.plugin.core.PluginLoader;
2120
import com.plugin.core.PluginDispatcher;
21+
import com.plugin.core.PluginLoader;
2222

2323
public class PluginDetailActivity extends Activity {
2424

PluginTest/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- 这里配置sharedUserId的作用,是为了告诉宿主程序,这个插件需要依赖宿主程序的class和资源
3+
如果不配置这个参数,表示这个插件是一个独立插件,即本身可以独立安装运行 -->
24
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
35
package="com.example.plugintest"
46
android:versionCode="1"

0 commit comments

Comments
 (0)