android--动态加载、插件化

本文介绍了Android动态加载和插件化的概念,阐述了业务需求和技术挑战,如65535方法数限制和快速迭代的需求。DynamicLoadApk框架提供了解决方案,包括核心概念如宿主、插件和组件,以及总体设计和详细设计。通过代理组件管理,实现资源访问和Activity生命周期管理。文章还探讨了框架的不足和待完善之处,以及与其他插件化方案的对比。
摘要由CSDN通过智能技术生成

何为动态加载、插件化?


需求驱动


随着业务发展需要和无线部门的拆分,各业务产品模块归属到各业务BU,原有无线App开发团队被分为基础框架、业务A、业务B、业务C等多个开发团队,从此App的开发和发布进入了一个全新模式。在这种模式下,开发沟通成本大大提高,之前的协作模式难以为继,需要新的开发模式和技术解决需求问题。

另一方面,从技术上来说65535方法数问题。旧方案是把所有第三方库放到第二个dex中,并且利用Facebook当年发现的hack方法扩大点LinearAllocHdr分配空间(5M提升到8M),但随着代码的膨胀,旧方案也逐渐捉襟见肘。拆or不拆,根本不是可考虑问题,继续拆分dex是我们的唯一出路。问题在于:怎么拆才比较聪明?

其次,随着组织架构调整的影响,给我们的App质量控制带来极高的挑战,这种紧张和压力让我们的开发团队心力憔悴。此时除了流着口水羡慕前端同事们的在线更新持续发布能力之外,难道就没有办法解决Native架构这一根本性缺陷了吗?NO!插件化动态加载带来的额外好处就是客户端的热部署能力。

从以上几点根本性需求可以看出,插件化动态加载架构方案会为我们带来多么巨大的收益,除此之外还有诸多好处




为什么开发者有需要?


contextimpl初始微程序装载

  1. 模块解耦
  2. 动态升级
  3. 高效并行开发(编译速度更快) 
  4. 按需加载,内存占用更低等等。

          Initial Microprogram Loading


编译速度提升

工程被拆分为十来个子工程之后,Android Studio编译流程繁冗的缺点被迅速放大,在Win7机械硬盘开发机上编译时间曾突破1小时,令人发指的龟速编译让开发人员叫苦不迭(当然现在换成Mac+SSD快太多)。


启动速度提升


Google提供的MultiDex方案,会在主线程中执行所有dex的解压、dexopt、加载操作,这是一个非常漫长的过程,用户会明显的看到长久的黑屏,更容易造成主线程的ANR,导致首次启动初始化失败。


A/B Testing

可以独立开发AB版本的模块,而不是将AB版本代码写在同一个模块中。


可选模块按需下载

​例如用于调试功能的模块可以在需要时进行下载后进行加载,减少App Size



具体怎么做?

动态加载主要有两个需要解决的复杂问题:资源的访问管理和activity生命周期的管理



下面具体分析一下这个DynamicLoadApk

DynamicLoadApk 提供了 3 种开发方式,让开发者在无需理解其工作原理的情况下快速的集成插件化功能。

  1. 宿主程序与插件完全独立
  2. 宿主程序开放部分接口供插件与之通信
  3. 宿主程序耦合插件的部分业务逻辑

三种开发模式都可以在 demo 中看到。

1.2 核心概念

(1) 宿主:主 App,可以加载插件,也称 Host。
(2) 插件:插件 App,被宿主加载的 App,也称 Plugin,可以是跟普通 App 一样的 Apk 文件。

(3) 组件:指 Android 中的ActivityServiceBroadcastReceiverContentProvider,目前 DL 支持ActivityService以及动态的BroadcastReceiver

(4) 插件组件:插件中的组件。

(5) 代理组件:在宿主的 Manifest 中注册,启动插件组件时首先被启动的组件。目前包括 DLProxyActivity(代理 Activity)、DLProxyFragmentActivity(代理 FragmentActivity)、DLProxyService(代理 Service)。

(6) Base 组件:插件组件的基类,目前包括 DLBasePluginActivity(插件 Activity 的基类)、DLBasePluginFragmentActivity(插件 FragmentActivity 的基类)、DLBasePluginService(插件 Service 的基类)。

DynamicLoadApk 原理的核心思想可以总结为两个字:代理。通过在 Manifest 中注册代理组件,当启动插件组件时首先启动一个代理组件,然后通过这个代理组件来构建、启动插件组件。

2. 总体设计

总体设计图
上面是 DynamicLoadApk 的总体设计图,DynamicLoadApk 主要分为四大模块:
(1) DLPluginManager
插件管理模块,负责插件的加载、管理以及启动插件组件。
(2) Proxy
代理组件模块,目前包括 DLProxyActivity(代理 Activity)、DLProxyFragmentActivity(代理 FragmentActivity)、DLProxyService(代理 Service)。
(3) Proxy Impl
代理组件公用逻辑模块,与(2)中的 Proxy 不同的是,这部分并不是一个组件,而是负责构建、加载插件组件的管理器。这些 Proxy Impl 通过反射得到插件组件,然后将插件与 Proxy 组件建立关联,最后调用插件组件的 onCreate 函数进行启动。
(4) Base Plugin
插件组件的基类模块,目前包括 DLBasePluginActivity(插件 Activity 的基类)、DLBasePluginFragmentActivity(插件 FragmentActivity 的基类)、DLBasePluginService(插件 Service 的基类)。

3. 流程图

流程图
上面是调用插件 Activity 的流程图,其他组件调用流程类似。
(1) 首先通过 DLPluginManager 的 loadApk 函数加载插件,这步每个插件只需调用一次。
(2) 通过 DLPluginManager 的 startPluginActivity 函数启动代理 Activity。
(3) 代理 Activity 启动过程中构建、启动插件 Activity。

4. 详细设计

4.1 类关系图

类关系图
以上是 DynamicLoadApk 主要类的关系图,跟总体设计中介绍的一样大致分为三部分。
(1) 对于 Proxy 部分,每个组件都存在 DLAttachable 接口,方便统一该组件不同类,如 Activity、FragmentActivity。每个组件的公共实现部分都统一放到了对应的 DLProxyImpl 中。
(2) 对于 Base Plugin 部分,每个组件都存在 DLPlugin 接口,同样是方便统一该组件不同类。

4.2 类功能介绍
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值