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


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

    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
    如果发现本文有什么问题和任何建议,也随时欢迎交流~

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

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

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

     

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

    相对于Dex和资源的更新,是不是简单很多。

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

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

    然后在下发补丁成功后根据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过程中所需要考虑的问题做一个阐述。

  • 相关阅读:
    Server-Sent Events(SSE) 简单实现和避坑
    使用ZIP进行多文件保存和读取(JDK1.7之后ZipOutputStream已经支持中文)
    IO
    页面临时添加a元素来模拟上传下载
    Centos 7启动jar包的详细步骤
    Redis 下载地址
    永久关闭win10自动更新
    同一命名空间下,无法引用类时
    Web应用程序项目******已配置为使用IIS。未能找到Web服务器
    VS2012打开项目 提示Asp.net4.0未在web服务器上注册的解决方案
  • 原文地址:https://www.cnblogs.com/yyangblog/p/6252855.html
Copyright © 2020-2023  润新知