Android插件化开发初探
原文来自:Android插件化开发 第一篇 [动态加载apk]http://blog.csdn.net/h3c4lenovo/article/details/50729395,感谢大神分享。
同系列:Android插件化开发 第二篇 [动态加载apk优化]:http://blog.csdn.net/h3c4lenovo/article/details/50730418,
Android插件化开发 第三篇 [加载插件资源]:http://blog.csdn.net/h3c4lenovo/article/details/50731943
Android插件化开发 第四篇 [加载插件Activity]:http://blog.csdn.net/h3c4lenovo/article/details/50739032
Android插件化开发 第五篇 [360 Droid Plugin]:http://blog.csdn.net/h3c4lenovo/article/details/50751643
正文:
随着应用版本的不断迭代,App变得非常庞大而臃肿。新需求接踵而至,旧需求废弃无用而占着空间,工程变得混乱。虽然会采用不同的包名隔离开各个需求模块,但是往往还是觉得如果需求能像插件一样分模块,需要的时候插上去,废弃的时候拔下来就好了。携程开源了其插件化开发框架(携程插件化开发框架),接下来我会学习并从本文开始介绍携程开源的这套插件化开发框架,让更多的人了解安卓的插件化开发。这里感谢携程团队的贡献,文章中如有描述错误或理解错误的地方,也希望大家指点。
这一篇里我们会仿照实现一个简单的插件化开发的例子,这个小例子原理简单的来说就是把一些辅助性的代码(如xxxUtils.Java)写在B项目里生成B.apk,把B.apk放到主项目A的assets文件夹中,利用反射的原理让A项目可以调用B.apk中的xxxUtils.java。其实可以更简单的理解为B是一个Android library。这样直接用apk反射调用而不是用library的形式有一个好处就是规避项目编译过程中的dex超过65535方法数Bug,也有可能是为了日后支持例如资源共享,界面跳转之类的,因为传统Android library是不能向宿主获取资源的。另外我们知道反射其实是相对消耗资源的一种调用方式,所以该框架在性能上是否会受到影响我们保留疑问继续学习。
Demo创建 创建一个工程PluginA,创建一个文件PluginAUtils.java,写上你想要的代码。如:public class PluginAUtils {
public void showToastInfo(Context context) {
Toast.makeText(context,"This is from pluginA",Toast.LENGTH_SHORT).show();
}
}
12345 12345编译成功后生成pluginA.apk
接下来创建工程PluginApp在app/src/main/目录下创建asserts文件夹,把刚刚编译好的pluginA.apk放到里面。创建一个AssertsDexLoader.java用来动态加载pluginA工程。
关键代码如下:
private static void installBundleDexs(ClassLoader loader, File dexDir, List<File> files, boolean isHotFix) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,InstantiationException, InvocationTargetException, NoSuchMethodException, IOException {
if (!files.isEmpty()) {
if (Build.VERSION.SDK_INT >= 23) {
V23.install(loader, files, dexDir,isHotFix);
} else if (Build.VERSION.SDK_INT >= 19) {
V19.install(loader, files, dexDir,isHotFix);
} else if (Build.VERSION.SDK_INT >= 14) {
V14.install(loader, files, dexDir,isHotFix);
} else {
V4.install(loader, files,isHotFix);
}
}
}
1234567891011121314 1234567891011121314AssertsDexLoader逻辑为拷贝asserts里的apk文件到系统的/data/data/appPackageDir/里,再把ClassLoader,拷贝的目录及文件三个参数传递给installBundleDexs()即可动态加载其方法至内存。
在任何需要的地方通过反射调用即可private void runAssertsDexMethod() throws Exception {
Class<?> clazz = Class.forName("h3c.plugina.PluginAUtils");
// Class<?> clazz = getClassLoader()
// .loadClass("h3c.plugina.PluginAUtils");
Constructor<?> constructor = clazz.getConstructor();
Object bundleUtils = constructor.newInstance();
Method printSumMethod = clazz.getMethod("showToastInfo", Context.class);
printSumMethod.setAccessible(true);
printSumMethod.invoke(bundleUtils, getApplicationContext());
}
12345678910 12345678910 [关键代码可参考这里]
[Demo可参考这里]
ClassLoader
ClassLoader顾名思义就是类的加载者,通俗的来说就是把class文件中的类加载到内存里。App启动的时候会创建一个自己的ClassLoader实例,将我们创建的ClassLoader挂载到App的ClassLoader下即可实现类的动态加载。
[ClassLoader详细介绍]
可能遇到的问题
App没有添加读写存储权限导致拷贝apk失败
无法找到插件apk里的类或方法,最大的可能是编译的插件化apk真的不包含该类或方法。推荐反编译插件apk(Android 在线反编译)检查类或方法是否真的被编译进去。(附上Mac的AS编译方法:Build->Build APK 运行结束后在工程文件夹/app/build/outputs/apk/app-debug.apk下找到这个Debug签名的apk)
由此可见此方法适合轻量级的插件化开发。
相关知识
快速搭建基于React Native的插件化Android工程快速搭建基于React Native的插件化Android
进阶高工必备技能:Android插件化技术全解析!(附项目实战+视频分享)
Android组件化开发实践
Android 组件化,从入门到不可自拔组件化技术,在 Android 开发中有着举足轻重的作用。 随着时间推移,软件项
Android入门开发经验
Android SystemUI的客制化 (1)
Android环境搭建心得体会(windows)
【Unity 三消游戏框架插件】Puzzle Match Kit 帮助快速创建和开发经典的三消类游戏(Match
Android架构体系化学习与面试题期刊
分享课程——uniapp+vue3+云开发全栈开发同城配送鲜花小程序任意商城项目
网址: Android插件化开发初探 https://www.huajiangbk.com/newsview1786886.html
上一篇: 数据结构23 |
下一篇: JS输出所有的3位水仙花数 |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039