Android热修复技术(一)

现在的android热修复技术大行其道,各大公司基本都有自己的一套热修复机制,顿觉是时候学习一波了,通过阅读了阿里的android热修复技术原理,收益颇丰,在这里写下一些理解。

在线出现了bug怎么办?

1、传统的更新流程是紧急修复,然后重新发布,但是需要用户进入应用商店,下载完成更新,显然用户体验非常差
2、因此有人想出了一种解决方案,采用Hybrid方案,把需要经常变更的业务逻辑用H5抽象出来,但是不仅增加了传统的java开发人员的学习成本,一些难以转换为H5的代码依旧是无法解决上述的问题。
3、插件化方案,比如Atlas,但是移植成本比较高,需要学习整套插件化工具,对于小中型的app,显得不合适了。
4、热修复技术。把更新补丁上传到云端,此时app直接从云端拉取出补丁并应用生效。因此出现bug后的流程是打出补丁,推送给用户,用户自动拉取补丁修复。

热修复方案好坏判断的指标

DEX修复,资源更新,so库更新,性能损耗,四大组件,生成补丁, 接入成本,安全机制,服务端支持等。
阿里的sopfix在以上各方面基本领先于微信的Tinker和饿了吗的Amigo,比如在DEX修复上支持即时生效和冷启动生效,在性能损耗上低,傻瓜式接入,只是不能支持四大组件修复,因为如果要支持,就必须在manifest里预先插入代理组件,并尽可能的声明所有的权限,这样使得app很臃肿。

代码修复方案

一种是阿里系的底层替换方案,另一种是腾讯系的类加载方案。
两种方法都各有优劣,底层替换方案限制比较多,但是时效性好,加载轻快;
类加载时效性差,需要冷启动才有效,但是修复范围广,限制少。

底层替换方案

底层替换方案是在已经加载了的类中替换已经存在的原有方法,不能对原有类进行字段和方法的增删
1、对类的方法不能增删的原因是一旦对方法进行了增删,势必会导致原有方法数的变化以及dex方法索引的变化,访问方法时就不能正常的访问了。
2、对字段不能进行增删的原因也大致一样,而且如果某一个类生成了一个实例,他原来的类的结构是无法改变的,如果新的方法使用老的对象访问新的字段这个肯定会出现问题的。
另外底层替换也是很不稳定的!
一般来说,传统的底层替换方案都是直接依赖于修改虚拟机方法实体的具体字段,例如更改jni函数指针,改类或者方法的访问权限。但是由于android是开源的,各大厂商都能对android底层源码进行修改,但是热修复方案中的ArtMethod的结构体是写死的,那么就容易发生问题。

sopfix 方案:
出于对兼容性和扩展性的考虑,sopfix实现了一种无视底层具体结构的替换方式,只要保证ArtMethod数组是以线性的结构进行排列,就能直接应用起来。具体是如何实现的,后面再阐述。

类加载方案

类加载方案的原理是在app重新启动后让Classloader去加载新的类。

往往将两种方法结合才是好的,针对小修改,在底层替换方案的限制内,就直接采用底层替换方案,可以做到代码的立即修复,如果代码修改超出底层替换限制的,会使用类加载替换。

资源修复方案

大多数的热修复方案都是参考了Instant Run的代码,Instant Run的资源修复方案分为两步:
1、构造出一个AssetManager,通过反射调用addAssetPath,并把这个完整的新的资源包加入到AssetManager中,这样就得到了一个含有所有新资源的AssetManager。
2、找到原来所有用到原来AssetManager的地方,利用反射,将引用处进行替换。

sopfix 方案:
构造了一个package id 为0x66 的资源包,这个包里只有改变了的资源项,直接在原有的AssetManager中addAssetPath就可以了,由于补丁包中的package id 为0x66 与原来的不一样,因此可以直接加入到原有的AssetManager中,并且在原有的AssetManager对象上进行析构和重构, 这样原有的AssetManager对象的引用是没有发生变化的。

好处:1、不修改AssetManager的引用,替换更快更安全。(对比Instant run)
2、不必下发完整包。(对比Instant Run 和Amigo)
3、不需要在运行时合成完整包,不占用计算机的内存资源。(对比Tinker)

SO库修复

sophix方案:
采用类似类修复反射注入方式,把补丁so库的路径插入到nativeLibraryDirectories数组最前面,达到加载so库的时候加载的是补丁的so库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值