Skip to content
kissonchan edited this page Jul 9, 2019 · 14 revisions

Qigsaw['tʃɪɡsɔ] -- 基于 Android App Bundle 动态化方案

Qigsaw 是什么

Qigsaw 是爱奇艺提供的一套基于 Android App Bundle 的动态化方案,无需谷歌 Play Service 即可在国内体验 Android App Bundle。它支持动态下发插件 APK,让应用能够在不重新安装的情况下实现动态安装插件。

为什么选择 Qigsaw

Qigsaw是爱奇艺自主研发的动态组件化框架,其核心优势如下:

  1. 利用Android App Bundle开发套件,极速开发体验。
  2. 支持Android App Bundle所有功能特性,"山寨"Play Core Library公开接口实现,开发者阅读官方文档即可愉快开发。
  3. 任何进程均可动态加载插件,支持Android四大组件动态加载。
  4. 如果您的应用有出海需求,可无缝切换至Android App Bundle方案。
  5. 仅一处Hook,少量私有API访问,保证框架稳定性。

国内 Android 插件化方案早已百花齐放,比如 DroidPlugin、Replugin、VirtualAPK 等。但这些插件化方案开发、维护成本都较高。

plugin_work_mode

插件化方案一般是基线工程和插件工程独立开发,基线工程提供基础 SDK 供插件工程编译使用,如此可以避免类重复问题。这种开发模式对于大公司来说可以接受,因为人力充足,业务线丰富。但对于对于高速发展的创业公司来说,反而会成为一种负担,因为需要额外开发人力服务于插件工程。

另外国内插件化方案一般将插件 APK 运行插件:plugin进程。如此您提供IPC方案,用于跨进程通信。

plugin_ipc

Qigsaw 完全利用 Android App Bundle 开发套件,插件作为一个模块和基线工程一起编译。

qigsaw_project_structure

Android App Bundle 提供新的Gradle-Plugin com.android.dynamic-feature, 用于编译插件。在整个工程中,Dynamic-Feature 模块可以使用其他任何模块,包括 Library、 Application、甚至其他Dynamic-Feature模块。您将以上帝视角俯视整个App工程,插件不再是围墙之外的孤儿。

开发阶段,你将享受 Android App Bundle 极速开发体验。

qigsaw_debug_mode

当您的项目编译完成后,Android Studio通过adb install-multiple命令将 base APK 和插件 APK 安装至手机中。如果您的开发手机系统版本低于5.0,则会依据当前手机设备组装成一个完整apk文件安装至该手机。

vivo手机不支持多 APK 安装功能,因此开发过程中请选取其他手机。或者使用Qigsaw打包插件提供的qigsawAssemble${variantName}命令

发布阶段,你将享受 Qigsaw 提供的一条龙服务,插件开发者不必关心插件 APK 的上传分发。

qigsaw_release_mode

Qigsaw打包插件支持内置插件,所有内置插件都会被拷贝至base apk的assets目录。对于非内置插件,Qigsaw打包插件会将其上传至CDN服务器(需要接入方实现上传CDN接口),解决业务方后顾之忧。

Qigsaw 目前在爱奇艺内部已有五个业务团队在使用,包括爱奇艺App和一些创新项目。国内的插件化方案,对于小团队来说开发维护成本很大,不仅需要维护Android工程相关SDK,还需要开发插件发布平台。Qigsaw 很好的解决这些问题,在爱奇艺一些创新项目中,Qigsaw发挥很大作用,为他们减少约20%~30%包体积。

Qigsaw 打包插件做的事情很少,因此当Android Gradle Plugin 或者 Gradle 升级时,Qigsaw 适配起来非常简单。然而国内插件化方案打包插件升级进度很慢,有些根本不再适配,严重阻碍开发效率。

Qigsaw 已知问题

  1. 插件无法更新AndroidManifest.xml,例如新增四大组件等。
  2. 无法动态更新base APK。
  3. 插件不支持增量更新。
  4. 不支持低于4.0的Android系统版本。
  5. 插件模块代码中如果使用System.load(..)方式加载插件so文件,请改为System.loadLibrary(...)方式加载。
  6. 其他更多已知问题请参考Android App Bundles

接入指引

实现插件上传CDN功能

Qigsaw 打包插件会在编译期间将插件上传需要动态加载的插件,因此您必须实现SplitApkUploader才能将split APK上传到您的CND服务器。

具体实现可参考SampleSplitApkUploader

自定义下载器

考虑到每个app都有自身的下载器,因此Qigsaw不提供具体下载服务而是暴露下载接口定义,交由接入方实现。Downloader需具有以下功能。

  1. sessionId唯一标识组任务。
  2. 支持组任务下载,取消组任务。
  3. 所有文件下载完成算作一次任务成功,下载过程中能返回所有已下载文件大小。
  4. 根据sessionId,能查询组任务下载状态。
  5. 能够设置组任务下载优先级,用于立即或延时安装插件。
  6. 如果文件已经下载,则不再下载。

具体实现细节可参考SampleDownloader

其他文章

爱奇艺重磅开源基于Android-App-Bundle动态化方案Qigsaw

Qigsaw遇上Tinker

Qigsaw Gradle Plugin参数概览

Clone this wiki locally