0

Aura插件化框架演进以及思考

 收集于1周前 阅读数 0
以下为 快照 页面,建议前往来源网站查看,会有更好的阅读体验。
原文链接: http://mp.weixin.qq.com/s?__biz=MzUyMDAxMjQ3Ng%3D%3D&%3Bmid=2247491737&%3Bidx=1&%3Bsn=dd095101eddcbfc5a9285157097a58e9
  • 在Android开发行业里,插件化已经不是一门新鲜的技术了,早在12年就已经被提出,发展到今天已经逐渐趋于成熟,各大厂商基本都有自己的一套插件化方案。

  • 京东的插件化框架Aura起始于2014年,相比于现在Android平台上的插件化框架百花齐放的盛况,在当时插件化框架可谓是凤毛麟角,可供参考的资料比较少,而仅有的几个开源项目也有它们各自的局限性,不适合大项目使用。我们在研究了当时的一些开源的技术之后,逐渐走出了一条自己的插件化框架之路,到如今形成了比较完善的插件化框架。

为什么要插件化

插件化技术的好处是显而易见的:

  • 模块解耦:随着业务的不断增加,代码库会逐渐臃肿,各个业务耦合情况将会越来越严重,造成开发调试的困难。插件间一般是没有耦合关系的,因此天然的支持模块解耦。

  • 协同开发:插件可以独立仓库开发,各个模块互不影响。

  • 提高编译速度:编译速度会极大的影响开发效率,话说编码五分钟,编译两小时,插件化后,宿主的编译速度会显著提升,并且各个插件也可以独立编译调试。

  • 动态发布:各个插件可以脱离宿主的发版限制独立发版,既可用于解决线上bug,也可以快速上线新业务。

  • 65536问题:插件化方案可以减少宿主的方法数。

  • 减小包体积:包体积和下载转化率有很大关系,Google曾经统计过包体积每增加6MB就会带来转化率1%的下降,并且Google Play也有过规定:对于发布到 Google Play 的应用,其下载大小限制为不超过100MB。插件包可动态下载,是减小宿主包体积的利器。

插件化带来这么多便利的同时,也会面临不少问题:

  • 兼容性:插件化技术或多或少会涉及hook系统的API,Google从Android 9.0开始限制私有API的调用,因此需要考虑兼容Android的各个版本,并且Android碎片化比较严重,需要兼容各大厂商的rom。

  • 复杂性:插件化技术的整体流程是比较复杂的,不仅涉及框架sdk,还需要Gradle插件甚至修改aapt等工具来实现插件包的编译。接入插件化方案也会有一定的成本。

插件化技术现状

  • Android插件化的历史并不长,自12年的AndroidDynamicLoader框架开始,到15年的DroidPlugin,16年的Small,再到17年的Atlas、Replugin、VirtualAPK,可谓是日新月异,百家争鸣,至此插件化技术进入了成熟阶段。 但好景不长,随着Android P的发布,Google官方推出了大杀器 -- 禁止调用私有API[1],插件化框架或多或少都会反射系统的隐藏API,Google此举似乎给插件化技术画上了句号。 不过好在私有API分为黑名单、灰名单、白名单三种方式,市面上大多数插件框架都作了兼容,调用系统API最多是在灰名单里,所以目前插件化框架仍然是可用的。 但这并不代表万无一失,灰名单是根据Target sdk 版本去划分的,后续的Android 系统仍会将某些API设为黑名单里,无疑给插件化技术的发展蒙上了一层阴影。 这里不得不佩服Replugin团队的技术前瞻性,仅使用一处hook点,hook点越少,涉及私有API的风险也就越低。 此后,插件化技术的发展似乎停滞不前,热度也越来越低。

  • 2018年Google发布了一种新的应用发布方式:Android App Bundle,可将应用拆分为多个Feature Apk,支持动态下发。这似乎是插件化的官方版本,不过这套服务依赖Google Play,国内环境无法使用,这种方式对插件化技术带来了新的方案。

  • 2019年,经过了一段时间的沉寂后,随着基于Android App     Bundle的Qigsaw插件化方案 和零反射全动态Android插件框架Shadow的开源,插件化技术似乎又活跃了起来。

Aura插件化方案

Aura是京东自研的一款插件化框架,目前不仅支持京东商城70+个业务插件的落地,还支持的京东到家、泰国站、拼购等App的使用,经过线上亿级用户量的检验,逐渐沉淀出的一套稳定的、灵活的插件化方案,并且提供了一整套编译、集成、动态升级流程,极大的简化了开发流程。 整体框架见下图:

VRnMzaQ.jpg!web

  • 系统层:hook了ClassLoader和Assetmanager用于插件类和资源的加载。

  • 框架层:包含Aura框架和公共库,公共库包含了插件和宿主共同依赖的类和资源。Aura框架则提供了插件化能力。

  • 插件层:基于公共库和插件框架进行开发,有业务插件和公共插件之分。

实现原理

目前市面上的插件化方案已经很多,实现原理也都比较透明了,这里再简单介绍下。 实现插件化框架主要是解决两个问题: 类的加载和资源加载。

  • 类加载:

1、Aura通过反射将系统的PathClassLoader替换成我们自己的DelegateClassLoader。

2、加载插件的时候会给每个插件创建自己的ClassLoader。

3、当启动插件中Activity或其他组件时候,DelegateClassLoader则会根据Activity名称找到对应的插件,执行安装过程,最终调用插件的ClassLoader进行类的加载。插件ClassLoader会优先加载插件内部的类,加载失败再用宿主的ClassLoader去加载。因此插件中是可以正常使用宿主中的API的。

  • 资源加载:

1、公 共资源是宿主工程和插件工程共用的部分,包括资源(图片、布局、样式、字符等)和代码,公共资源集成在宿主工程, 插件可以直接使用。 为了保证能正确的使用公共库里的资源,Aura通过维护公共资源的public.xml文件来保证插件工程和宿主工程使用相同的资源id,不出现资源错乱的问题。 并且插件包中只集成插件内部的资源和代码,不会集成公共库里的内容,以减小插件包的体积。

2、插件工程是独立编译的,正常apk的资源packageId是0x7f,为了保证插件内部的资源不和宿主冲突,需要修改插件的packageId,保证每个插件都分配有自己唯一的packageId,packageId范围0x21~0x7E相对比较稳妥。

3、运行期间通过反射宿主AssetManager中的addAssetPath方法,将插件的路径添加到宿主的资源路径里去,这样就实现了插件资源的加载。

IvM3UvR.jpg!web

插件管理

插件编译流程比较复杂,需要对packageId进行重排,以及 去除公共库里的资源及代码,并且由于插件是独立编译的,宿主如何正确、高效的集成插件包也是需要考虑的问题。 因此我们也开发了一套对应的管理平台和Gradle工具来简化这一流程,插件编译、版本管理、集成进 宿 以及宿主的编译都可以在管理平台里进行操作。

rQ3yauE.jpg!web

插件升级

插件可 以脱离宿主的发版限制独立发版,既可用于解决线上bug,也可以快速上线新业务。 Aura插件化框架提供了完整的插件升级服务,可以针对宿主VersionName、VersionCode、系统api版本等多个维度进行升级发布。

2UJFbum.jpg!web

Aura插件化框架的思考

  • Aura框架hook了系统的API,因此需要紧跟Android的版本节奏进行兼容, Android 9、Android 10等系统的兼容,小米、索尼等rom的兼容,因此后续如何减少私有API的调用,以及寻求更稳健的实现方式,是我们需要关注的一个点。

  • Aura插件使用我们提供的Grade工具AuraPlugin进行编译,由于Grade版本和Android Gradle Plugin的版本更新速度很快,因此AuraPlugin对各个版本的Grade进行兼容也是项繁重的工作。前面提到过,Google在2018年推出了“官方动态化组件技术” App Bundle[2],虽然在国内环境无法使用,但却和插件化技术的思路不谋而合。从下图可以看出,App Bundle会包含三种类型的APK:Base APK,Configuration APK和Dynamic feature APK。这里重点关注下Dynamic     feature APK,该APK的packageId是小于0x7f的,不同的Feature Apk的packageId也都是不同的,并且Dynamic feature模块的编译也会移除宿主app里的依赖。这和Aura插件的构建流程是类似的,因此兼容官方的Feature Apk构建也是一个重要的方向。

JZRNniu.jpg!web

s plit APKs结构[3]

总结

Aura插件化框架的目标是打造一套更加稳定高效的开发引擎,不断完善自身的能力,以满足不同的业务场景,并围绕框架打造一套开发工具和平台,从而帮助开发者能更专注与业务层代码,提升开发效率。 我们仍在努力完善中。

参考链接

[1]https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces

[2] https://developer.android.com/platform/technology/app-bundle

[3] https://developer.android.com/studio/projects/dynamic-delivery


猜你喜欢

关于极客头条


聚合每日国内外有价值,有趣的链接。