【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

本系列将从如下三个方面对Tinker进行源码解析:html

  1. Android热更新开源项目Tinker源码解析系列之一:Dex热更新
  2. Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
  3. Android热更新开源项目Tinker源码解析系类之三:so文件热更新

 

转载请标明本文来源:http://www.cnblogs.com/yyangblog/p/6252855.html
更多内容欢迎star做者的github:https://github.com/LaurenceYang/article
若是发现本文有什么问题和任何建议,也随时欢迎交流~git

首先讲下Android里面关于so的加载的两种方式:github

方式一:System.loadLibrary, 这种方式传入的是so的名字,会直接从系统的目录去加载so文件,系统的路径包括/data/data/${package_name}/lib、/system/lib、/vender/lib等这类路径。算法

方式二:System.load, 这种方式传入的是so的绝对路径,直接从这个路径加载so文件。框架

 

Tinker的so文件热更新的原理就是经过方式二,直接加载新的so实现的。spa

相对于Dex和资源的更新,是否是简单不少。code

 

so文件的热更新流程同dex、资源文件同样,包含补丁生成,补丁合成,补丁加载三个部分。htm

 

生成补丁时比较新旧so文件使用BSdiff算法生成补丁包,blog

而后在下发补丁成功后根据BSpatch算法将补丁包和旧的library合成新的library,资源

并将更新后的Library库文件保存在tinker下面的目录下,

这个目录就是/data/data/${package_name}/tinker/lib。

而后在加载的时候直接经过System.load加载该目录下面的so文件。

具体的源码再也不作阐述。

 

须要注意的是,Tinker中so的热更新对用户并非无感的,须要用户自发的去加载本身须要的库文件,下面是tinker的wiki里关于这方面的描述:

可是Tinker并无直接将补丁的lib路径添加到DexPathList中,理论上这样能够作到程序彻底没有感知的对Library文件做补丁。这里主要是由于在多abi的状况下,某些机器获取的并不许确。

因此想要加载最新的库,须要本身使用TinkerInstaller.load*Library去加载库文件,它会自动尝试先去Tinker中的库文件加载,加载不成功会调用System.loadLibrary调用系统的库文件。

1 //load lib/armeabi library
2 TinkerInstaller.loadArmLibrary(getApplicationContext(), "stlport_shared"); 3 //load lib/armeabi-v7a library
4 TinkerInstaller.loadArmV7Library(getApplicationContext(), "stlport_shared");

 

另外,对于第三方库文件的加载,Tinker没法干预其加载时机,可是只要在咱们的代码提早加载第三方的库文件便可。

若想对第三方代码的库文件更新,可先使用TinkerInstaller.load*Library对第三方库作提早的加载!

当前使用方式彷佛并不能作到开发者透明,这是由于Tinker想尽可能少的去hook系统框架减小兼容性的问题。

 

到此,tinker的源码解析系列到此结束。

本系列从dex,资源文件和so的补丁生成,补丁合成和补丁加载角度出发,作了一个简要的流程分析。

由于本身水平有限,不少地方也没有太过深刻。

对tinker感兴趣的同窗能够到tinker的官方github去看更多的文档。

也欢迎你们多多拍砖。

 

转载请标明本文来源:http://www.cnblogs.com/yyangblog/p/6252855.html
更多内容欢迎star做者的github:https://github.com/LaurenceYang/article
若是发现本文有什么问题和任何建议,也随时欢迎交流~

 

 下一篇文章将对在实际使用tinker过程当中所须要考虑的问题作一个阐述。

相关文章
相关标签/搜索