《深入探索Android热修复技术原理》读后感以及插件化思考

2024-05-02 12:32

本文主要是介绍《深入探索Android热修复技术原理》读后感以及插件化思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近编辑于2019/02/17

主要介绍了阿里Sophix方案。

热修复的概念:

AndroidManifest出现BUG是无法修复的,想增加四大组件,可通过预先在安装包的AndroidManifest里面埋入代理的组件,在每次新增组件时,通过预埋的代理组件实现与系统进程间的通信。

热修复需要在补丁包中包含一个新逻辑的dex文件。

资源的修复,主要通过修改资源包的内容。

so库修复是通过在加载时优先加载补丁包的so库。

 

热替换代码修复:

Andfix底层替换的局限性:Andfix是根据公开的Android源码对ArtMethod结构体里面的字段进行的修改。如果手机厂商修改了ArtMethod的结构体(其实是在结构体前面增加字段,编译为AOT机器码后发生替换错位),就会导致机型不支持。

而Sophix采用了整体替换ArtMethod的方案,就避免了手机厂商修改结构体的问题。但也带来需要计算ArtMethod大小的问题,后来发现ArtMethod Array的地址是紧密排列的,通过相邻两个ArtMethod的起始地址的差值计算出ArtMethod的大小。优点只要以后ArtMethod数组仍是以线性结构排列,该方案仍能适用。

访问权限的问题:通常是因为类是由不同的Classloader加载导致的,可以通过反射或者采用冷启动的方式来解决。

热替换的局限:因为热替换需要原有的类实例的结构不变。因此使用Sophix进行热修复,想让用户体验到热替换,只能在原有类的方法里修改或者新增一个原包不存在的新类(PS这样会使代码变乱,在上升级包前应该重新整理代码)。还有其他一些局限:比如尽量不要增加非静态内部类、需要混淆配置加上-dontoptimize防止方法裁剪与内联、防止因泛型类型擦除与多态矛盾而产生的桥接方法、基本不支持Lambda表达式、补丁类不能引用非public类。

 

冷启动代码修复:

QQ空间和Tinker的冷启动方案与前面的热部署模式不兼容,Sophix寻求一种既能无侵入打包又能做热部署的补充解决方案。QQ空间使用的插桩(需要增加一个含有无关帮助类的dex,原dex中所有类的构造函数都引用这个类)会影响类加载效率。Tinker采用了把原有dex和补丁包里的dex重新合并的方案,Sophix则采用去除基线包中的补丁类再加上补丁。Tinker对Application的处理是需要开发者将自己的Application替换成TinkerApplication,而Sophix直接再JNI层去除Application类的pre-verified标志(需要Application用到的所有非系统类都和Application位于同一个dex里,因为Android官方multi-dex机制会自动将Application用到的类都打包到主dex中,所以只要把热修复初始化放在attachBaseContext的最前面就行),同时Sophix提供了指定AndroidManifest的Application为SophixStubApplication的方案(会解决一些入口类的问题,同时也不影响用户通过设置SophixEntry自定义Application)。

Android APP的启动顺序:Application.attachBaseContext——>ContentProvider.onCreate——>Application.onCreate——>Activity.onCreate。

 

资源热修复技术:

普遍的做法是参考Instant Run,把资源热修复分为两步:

1、构造一个新的AssetManager,并通过反射调用addAssetPath,把这个完整的新资源包加入到AssetManager中。这样就得到了一个含有所有新资源的AssetManager。

2、找到所有之前引用到原有AssetManager的地方,通过反射,把引用处替换为新的AssetManager。

Sophix采用了另辟蹊径的方案,主要是使补丁包的pacakage id为0x66,使其不与已经加载的资源冲突(修改资源时,还需在代码引用处做出相应修改,因为原先的资源还是存在的)。

 

so库热修复技术:

由于so库热部署的种种限制,Sophix采用了反射注入重启生效的冷启动方案。

 

 

编辑于2019/02/18

插件化思考

插件化技术类似于热修复技术,插件化更注重于多个插件的版本控制,也更注重于插件的即插即用(无需冷启动更新),但也由于不涉及原类的修改使得即插即用成为可能。

插件化也分为so库的加载、资源的加载、代码的加载。

so库的加载使用了System.load或者System.loadLibrary的方案,如同上面那本书中所讲,实际是存在一定限制的。

资源的加载也是从参照Instant Run的方案(我的一个无侵入支持应用内以及插件式的安卓应用换肤框架就是采用的这种方案)到修改资源id的技术衍变。

由于无需修改原类,使得代码的即插即用成为可能。这是插件化着重研究的方面。简单一点的如同上面热修复技术提到的预先在安装包的AndroidManifest里面埋入代理的组件,在每次新增组件时,通过预埋的代理组件实现与系统进程间的通信。复杂一点主要是运用静态代理进行Hook,或者动态代理进行Hook(Shawn_Dut 讲解了Android 动态代理以及利用动态代理实现 ServiceHook,GitHub上的源码,只不过插件化需要Hook的对象很多以及一些其他细节问题需要考虑)。

 

这篇关于《深入探索Android热修复技术原理》读后感以及插件化思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954251

相关文章

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

游戏闪退弹窗提示找不到storm.dll文件怎么办? Stormdll文件损坏修复技巧

《游戏闪退弹窗提示找不到storm.dll文件怎么办?Stormdll文件损坏修复技巧》DLL文件丢失或损坏会导致软件无法正常运行,例如我们在电脑上运行软件或游戏时会得到以下提示:storm.dll... 很多玩家在打开游戏时,突然弹出“找不到storm.dll文件”的提示框,随后游戏直接闪退,这通常是由于

Python实现PDF按页分割的技术指南

《Python实现PDF按页分割的技术指南》PDF文件处理是日常工作中的常见需求,特别是当我们需要将大型PDF文档拆分为多个部分时,下面我们就来看看如何使用Python创建一个灵活的PDF分割工具吧... 目录需求分析技术方案工具选择安装依赖完整代码实现使用说明基本用法示例命令输出示例技术亮点实际应用场景扩

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期