Android热修复技术 --- 兼容性问题深入

Android热修复技术2中,利用动态加载dex实现了热修复,当然这也是一个实现,Tinker也是利用这个原理实现的,但是其中还是会存在兼容性问题的,接下来就会介绍,热修复中存在的兼容性问题

1 Android N混合编译

在了解Android N(7.0)混合编译之前,首先对Android的编译过程做一些回顾

1.1 Dalvik时代

在Android 5.0之前,Android的虚拟机为Dalvik虚拟机,用于将dex文件转换为系统能够识别的机器码,每次执行这段代码都需要重新转换,效率很低;

因此在2.2版本,Google引入了JIT(即时编译技术),当App运行的时候,当遇到一个新的类的时候会做编译,但是会被优化成一个精简的原生指令码,下次再执行的时候,速度会很快;但是缺点就在于,当App重启的时候,还是会重新JIT

那面对这样的问题,Android在5.0之后,就完全废弃掉了Dalvik虚拟机,进入ART的时代

1.2 ART时代

在Android 5.0之后,ART替代了Dalvik,ART之所以会出现,就是解决Dalvik时代JIT的问题,虽然JIT能够对频繁执行的代码做dex优化,减少以后的编译时间,那也只是在运行时,而且dex翻译成机器码也需要时间;

因此ART虚拟机采用了AOT来代替JIT,当应用第一次安装的时候,会将全部的dex文件翻译成机器码存储在本地,等下次重启应用的时候,就直接拿本地的机器码,效率提升了很多,但是随之也带来了问题

1 安装时间

因为编译的过程非常耗时,在应用安装时会画很长时间等待,影响用户体验;当前app我可能只需要使用20%的功能,却多花了80%的时间等待

2 存储空间

AOT会对所有的dex文件做编译,10M的dex翻译成的机器码内存激增4-5倍,无效的资源占据了大量的内存空间

因此对AOT和JIT的两种方式做了对比,各有自己的优势,因此Android N之后,推出了一个全新模式 – 混合编译

1.3 混合编译

混合编译,就是将AOT、解释、JIT做了融合,各取所长。当App安装时,不做全量编译,而是解释字节码(有明白是啥意思的吗?),所以能够快速地安装启动;新增了一个新的JIT解释器,作用跟Dalvik的JIT类似,是在App运行时分析代码,把分析结果保存在Profile中,在设备空闲或者充电的时候,分析并编译这些代码

Android N的编译模式有12种,在空闲时间的时候,就会触发kSpeedProfile(speed-profile)编译模式

enum Filter {   
    VerifyNone,           // Skip verification but mark all classes as verified anyway.
    kVerifyAtRuntime,     // Delay verication to runtime, do not compile anything.
    kVerifyProfile,       // Verify only the classes in the profile, compile only JNI stubs.
    kInterpretOnly,       // Verify everything, compile only JNI stubs.
    kTime,                // Compile methods, but minimize compilation time.
    kSpaceProfile,        // Maximize space savings based on profile.
    kSpace,               // Maximize space savings.
    kBalanced,            // Good performance return on compilation investment.
    kSpeedProfile,        // Maximize runtime performance based on profile.
    kSpeed,               // Maximize runtime performance.
    kEverythingProfile,   // Compile everything capable of being compiled based on profile.
    kEverything,          // Compile everything capable of being compiled.
};

speed-profile模式会将运行时收集到的“热代码”做编译,这是不就有点儿像JIT了,会生成名为app_image的base.art文件,这个art文件会在类加载之前自动加载(类似于缓存)

问题来了!!!!!!如果我们要热修复的类是存在base.art中,就无法修复!!!!

问题当然是可以解决的,app_image中的class是插入到PathClassLoader中的ClassTable,我们的application一定会被PathClassLoader加载的,所以有一个方式就是,通过动态替换ClassLoader,这样摒弃app_image缓存,就能解决问题,但是会带来性能的损耗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Awesome_lay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值