安卓之热修复插件化

news/2024/7/16 8:01:38 标签: intellij-idea, java, ide, 面试, android
  • 插件化的定义

插件化(Pluginization)是指以插件形式将某个功能集成到一个系统或应用程序的过程。通俗地说,就是把应用的某些功能从原应用中分离出来,作为独立的插件,进行封装和部署,使得用户可以在原应用中动态添加、更新或删除这些插件,而不必对原应用进行修改和重新编译。

  • 插件化的优势

  1. 模块化开发和维护:通过将应用中的不同功能分解成独立的模块,可以使得开发者更加专注于每个模块的实现和维护,从而提高代码质量和可维护性。

  2. 动态更新和升级:对于应用程序中的某些功能模块,可以独立进行更新和升级,不会影响整个应用程序的发布和部署,大大提高了应用程序的可靠性和灵活性。

  3. 减少内存消耗和编译时间:由于插件化技术可以将应用程序的某些功能以插件的形式动态加载,因此在运行时只需要加载必要的插件,避免了不必要的内存消耗,同时也减少了应用程序编译的时间。

  4. 提升用户体验:通过插件化技术,可以将应用程序的某些功能模块以插件的形式单独打包、下载、安装和卸载,给用户带来了更好的使用体验,也增加了用户粘性。

  5. 节省开发成本:通过插件化技术,应用程序的不同功能模块可以由不同的开发者或团队进行并行开发,从而达到提高开发效率和节约开发成本的目的。

  • 插件化框架对比

目前比较流行的 Android 插件化框架主要包括:VirtualApk、DroidPlugin、DynamicAPK、Ranger、Small、RePlugin 等。

下面是几个主要插件化框架的对比:

  1. VirtualApk

VirtualApk 是美团点评开源的一款插件化框架,其最大的优势在于兼容性和稳定性上表现出色,支持插件与宿主共用进程,能够避免进程通信所带来的性能问题。同时,VirtualApk 还提供了丰富的插件生命周期管理、资源隔离等功能,可实现精密的插件运行状态监测和异常响应机制。

  1. DroidPlugin

DroidPlugin 由360手机卫士开发并开源,是一款功能齐全的插件化框架,在集成、使用和文档方面都很完善。该框架能够灵活地控制每个插件的进程、权限、升级、优先级等,并通过 APK 加载方式使得插件启动更为简单快速。

  1. DynamicAPK

DynamicAPK 是一款社区贡献型的插件化框架,致力于提升 Android 应用的动态特性和组件化开发方式。该框架支持多种插件加载模式,支持 Activity、Service、Broadcast 等组件的扩展,并拥有相对友好的文档和示例代码。

  1. Ranger

Ranger 是一个国产插件化框架,由小米开发并推广。该框架精简、轻量且快速,控制面板比较简单易用,能够实现插件的异步加载和卸载等功能,同时还提供了插件异常信息报告、CRASH 上报等完整的调试机制。

  1. Small

Small 是一种基于微内核架构实现的插件化框架,由阿里巴巴出品并推广。该框架可以在应用程序中自由地添加和删除插件,更可将插件和宿主进行隔离,启动切换频繁,性能表现出色。

  1. RePlugin

RePlugin 是 Ctrip 出品的另一款优秀的插件化框架,与 VirtualApk 类似,其优势在于兼容性、稳定性及运行效率上的优异表现。该框架的 Model 插件和 View 插件分别使用不同的类加载器来实现隔离,支持框架与逻辑分离,在多线程及并发访问方面具备优秀的表现。

  • 插件化流程

  1. 开发插件代码

首先需要开发出一个独立的插件,也就是一个 APK 包,拉通工程之后进行开发和测试。在开发过程中,必须考虑插件和宿主之间的交互方式,尽可能避免全局变量、单例、静态等影响插件与宿主的隔离。

  1. 宿主接入插件框架

通过引用插件框架库,在系统内部实现动态加载插件 APK 包。插件框架要求宿主程序自定义ClassLoader 和Resource来代替系统原有的ClassLoader和Resource。常见的插件框架有上文所述的 VirtualApk、DynamicAPK、RePlugin 等。

  1. 插件打包

由于插件和宿主属于两个不同的 APK 包,所以最终需要将插件打包成 apk 并进行签名。这里涉及到“v1”、“v2” 签名的问题,对应 Android Studio 中的两种打包方式 “debug”和“release”。

  1. 上传插件至服务器

可以将打包签名完成的插件直接上传至服务器,以供下载和安装,也可以打包成“patch”包形式,将更新信息存放在服务器,并根据用户需要实现实时下载和更新。

  1. 下载、加载插件

应用启动时,宿主会根据需要自行下载或是从服务器获取要加载的插件,将其解压并存放在设备某个位置中。同时可采取缓存策略,缓存已下载的插件,避免重复网络请求和流量消耗。

  1. 运行插件

插件经过加载之后,还需要进行一些必要的初始化操作,比如设置自定义类加载器、Context 上下文等,最终通过 Intent 启动 Activity 或 Service 等组件运行,并将返回结果传递回宿主。

  • 插件化类加载原理

  1. 共享 ClassLoader 实现

这是一种最简单、最常见的插件化类加载方式,常用于 Dex 文件动态加载。该方法需要在宿主程序中创建一个共享的 ClassLoader,并且将其传递到宿主和插件中。当某个 Activity 或 Service 被启动时,都会优先从该 ClassLoader 中查找对应的类信息。

插件部分通过调用 Activity.getClassLoader() 取得宿主 ClassLoader(即共享ClassLoader) 的引用, 通过反射调用 DexPathList 中的 makeDexElements 方法取得当前 Dex 的所有 Class 对象, 最后又插入到“gDefault”

缺点:容易发生类命名冲突和资源耗尽导致崩溃等问题。

  1. 自定义 ClassLoader 实现

为了避免共享 ClassLoader 的相关问题,很多插件化框架选择使用自定义 ClassLoader 实现插件的加载,并将每个插件使用独立的 ClassLoader 加载,以保证插件与宿主之间的隔离性。

该方法相对于上一种方式更加灵活,能够更好地实现资源隔离、插件生命周期控制等功能。同时,这种方式还可以通过 Hook 系统 ClassLoader 的方式实现对系统类的修改与扩展。

缺点:需要处理一些细节问题,如插件无法共享宿主资源及系统资源、启动时间常常相对较长、适配插件中使用的第三方库等问题。


http://www.niftyadmin.cn/n/378841.html

相关文章

WuThreat身份安全云-TVD每日漏洞情报-2023-05-26

漏洞名称:Barracuda Email Security Gateway TAR文件命令注入 漏洞级别:严重 漏洞编号:CVE-2023-2868,CNNVD-202305-2128 相关涉及:Barracuda Email Security Gateway 5.1.3.001 漏洞状态:在野 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-12949 漏洞名称…

PyCharm使用指南 - 如何创建密码短语生成器(上)

PyCharm是一种Python IDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外,该IDE提供了一些高级功能,以用于Django框架下的专业Web开发。 PyCharm 最新下载 本文将展示如何使用免费的 PyCharm Community Edition 开…

MFC (四) 处理文本

默认消息的处理方法 1.确认什么消息 2.添加消息处理函数 3.添加代码 默认消息指在消息定义中已存在的消息 这里我们对文本做换行处理 1.我们在ondraw里修改代码,这样,无论放大,缩小,都不会改变文本 void CMFCpaintView::On…

【网络】· 路由器中配置单臂路由和DHCP,VTP原理

目录 🍉单臂路由的工作原理 🥝交换机配置 🥝路由器配置 🍉路由器配置DHCP 🥝配置实例 🥝路由器配置 🥝验证 🍉VTP工作原理 🥝VTP模式 🥝VTP通告 &#x1f95d…

港联证券今日投资前瞻:人工智能再迎催化 关注房地产板块超跌机会

昨日,A股午后探底回升,沪指尾盘翻红,深成指、创业板指走高。截至收盘,沪指微涨0.09%报3224.21点,深成指涨0.44%报10869.55点,创业板指涨0.67%报2218.6点,科创50指数涨1.56%;两市合计…

经典神经网络(6)ResNet及其在Fashion-MNIST数据集上的应用

经典神经网络(6)ResNet及其在Fashion-MNIST数据集上的应用 1 ResNet的简述 ResNet 提出了一种残差学习框架来解决网络退化问题,从而训练更深的网络。这种框架可以结合已有的各种网络结构,充分发挥二者的优势。 ResNet以三种方式挑战了传统的神经网络架…

Java中字符串占位替换、字符串拼接、字符串与Collection互转的方式

场景 字符串占位替换 1、String.format 最原始最基础的方式。 使用%来表示占位,后面跟上不同的标识符,用于限定这个占位符的参数类型,由jdk原生提供支持。 示例: String badao String.format("hello:%s", "b…

记录一次把github上拉取的代码提交到私有仓库

在我们的日常开发工作中,有时我们需要从开源的GitHub项目中获取代码,然后将这些代码上传到我们自己的私有仓库。这样的操作似乎简单,但是如果你没有正确地处理,就可能会遇到各种问题。因此,我决定在这篇博客中详细记录…