通俗易懂来讲就是,拆成多个module开发就是组件化。
App的部分功能模块在打包时并不以传统⽅式打包进apk⽂件中,⽽是以另⼀种形式⼆次封装进apk内部,或者放在⽹络上适时下载,在需要的时候动态对这些功能模块进⾏加载,称之为插件化。这些单独⼆次封装的功能模块apk,就称作插件,初始安装的apk称作宿主。插件化是组件化的更进⼀步推进。
try {
Class utilClass = Class.forName("com.hencoder.demo.hidden.Util");
Constructor utilConstructor = utilClass.getDeclaredConstructors()[0];
utilConstructor.setAccessible(true);
Object util = utilConstructor.newInstance();
Method shoutMethod = utilClass.getDeclaredMethod("shout");
shoutMethod.setAccessible(true);
shoutMethod.invoke(util);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
JAVA既然提供了可⻅性关键字public、private等等,⽤来限制代码之间的可⻅性,为什么⼜要提供反射功能?可⻅性特性的⽀持不是为了代码不被坏⼈使⽤,⽽是为了程序开发的简洁性。安全性的话,可⻅性的⽀持提供的是Safety
的安全,⽽不是Security的安全。即,可⻅性的⽀持让程序更不容易写出bug,⽽不是更不容易被⼈⼊侵。反射的⽀持可以让开发者在可⻅性的例外场景中,可以突破可⻅性限制来调⽤⾃⼰需要的API。这是基于对开发者在使⽤反射时已经⾜够了解和谨慎的假设的。所以,可⻅性的⽀持不是为了防御外来者⼊侵,因此反射功能的⽀持并没有什么不合理。
关于DEX:
通过⾃定义ClassLoader来加载新的dex⽂件,从⽽让程序员原本没有的类可以被使⽤,这就是插件化的原理。 例如:把Utils拆到单独的项⽬,打包apk作为插件引⼊:
File f = new File(getCacheDir() + "/demo-debug.apk");
if (!f.exists()) {
try {
InputStream is = getAssets().open("apk/demo-debug.apk");
int size = is.avAIlable();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer);
fos.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
DexClassLoader classLoader = new DexClassLoader(f.getPath(),
getCodeCacheDir().getPath(), null, null);
try {
Class oldClass = classLoader.loadClass("com.hencoder.demo.hidden.Util");
Constructor utilConstructor = oldClass.getDeclaredConstructors()[0];
utilConstructor.setAccessible(true);
Object util = utilConstructor.newInstance();
Method shoutMethod = oldClass.getDeclaredMethod("shout");
shoutMethod.setAccessible(true);
shoutMethod.invoke(util);
Class activityClass = classLoader.loadClass("com.hencoder.demo.MainActivity");
startActivity(new Intent(this, activityClass));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
解决⽅式:⾃定义AssetManager和Resources对象
private AssetManager createAssetManager (String dexPath) {
try {
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, dexPath);
return assetManager;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
作者:包子是只猫
链接:
https://juejin.cn/post/7120149793489289247