赞
踩
在Android热修复技术2中,利用动态加载dex实现了热修复,当然这也是一个实现,Tinker也是利用这个原理实现的,但是其中还是会存在兼容性问题的,接下来就会介绍,热修复中存在的兼容性问题
在了解Android N(7.0)混合编译之前,首先对Android的编译过程做一些回顾
在Android 5.0之前,Android的虚拟机为Dalvik虚拟机,用于将dex文件转换为系统能够识别的机器码,每次执行这段代码都需要重新转换,效率很低;
因此在2.2版本,Google引入了JIT(即时编译技术),当App运行的时候,当遇到一个新的类的时候会做编译,但是会被优化成一个精简的原生指令码,下次再执行的时候,速度会很快;但是缺点就在于,当App重启的时候,还是会重新JIT
那面对这样的问题,Android在5.0之后,就完全废弃掉了Dalvik虚拟机,进入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之后,推出了一个全新模式 – 混合编译
混合编译,就是将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缓存,就能解决问题,但是会带来性能的损耗
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。