前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 4.x加载so失败问题原因分析

Android 4.x加载so失败问题原因分析

作者头像
stringwu
发布2022-08-12 11:56:39
9190
发布2022-08-12 11:56:39
举报

1 so 加载过程

so 加载的过程可以参考小米的系统工程师的文章loadLibrary动态库加载过程分析[1]

2 问题分析

2.1 问题

年前项目里新加了一个 so库,但发现native 方法的找不到的 crash 好多,好些都是报了java.lang.unsatisfiedlinkerror native method not found,而且基本上是出现在4.x的系统里,特别是 4.4,4.2的系统。在网络上搜索相关的可能导致到这个问题的原因:

•so 文件没有在对应架构的目录里找到;•方法名有错误;

2.2 分析1

我们最开始是怀疑应用在安装时没有正确解压出对应的so文件到相应目录,因此加了相应统计来看发生crash的手机是否是因为找不到对应的 so文件导致的;但统计数据发现这些手机里都可以找到对应架构的 so文件,因此就排除了不存在so文件导致的 crash;

2.3 分析2

我们同事以前有发现在Android 4.x系统里,如果so 文件是在应用启动时加载的,但使用时机却在后面的时间点,so加载进手机的内存可能会被系统由于资源紧张而回收掉,这种情况下,可以通过重新加载一次 so文件来减少相关的 crash,这种方法 fix了某个量很高的 so 相关的crash。但我们的 socrash 明显是不属于这种情况的,因为我们是通过 System.load() 方法加载完 so文件后,就调用相关的方法,这时内存肯定是还在的。在分析了一系列可能的原因后,怀疑这个crash 是因为应用安装时解压出来的 so文件是损坏的,因此我们尝试在第一次发生这个crash时,将这个crash catch住,然后在 catch块将原来目录下的 so文件删除掉,并重新从应用的安装目录解压出对应的so文件放到原来的目录,并加了相关的统计来验证。so的加载用了 Relinkder[2]。相关的简化版本代码如下:

代码语言:javascript
复制
relinker.loadLibrary(getApplicationContext(), "so_name");
try{
  // call native method
} catch(UnsatisfiedLinkError e) {
  //some stats
   String library = "so_name";
   String libName = System.mapLibraryName(library);
   File workaroundLibDir = getApplicationContext().getDir("lib", Context.MODE_PRIVATE);
   File workaroundLibFile = new File(workaroundLibDir, libName);
   workaroundLibFile.delete();
   apkLibraryInstaller.installLibrary(
                          getApplicationContext()
                          , supportedAbis()
                          , libName
                          , workaroundLibFile
                          , relinker
                  );
   System.load(workaroundLibFile.getAbsolutePath());
   //call native method
   // some stats
}

2.4 分析3

在使用的 2.3 的解决方法后,我们的 sojava.lang.unsatisfiedlinkerror native method not found 大部分消失了。理论上使用过一次重新解压so 文件后,这个用户在下一次升级前都应该不会再发生了类似的 crash了,但我们的统计数据发现,有些用户每一次启动都需要进入catch块来避免crash,而每次都可以通过 reload来正常使用我们的应用,这至今还是个迷,还没有想明白是什么情况会导致这个问题?手机的存储有问题?但其他的so又没有这个问题。希望如果有同行解决过类似的问题的,指点一下。

3 总结

Android 4.X 系统加载 so 后,出现 java.lang.unsatisfiedlinkerror native method not foundcrash的原因除了网上所说的 不存在这个so 和 方法名有问题(商用的应用应该不会有这个问题的)外,还有两个原因:•so 加载进系统的内存被系统由于资紧张而回收了,这种情况下直接再load一下 so 文件就可以解决大部分;•so 文件有问题,这种情况下,可以通过重新从应用安装目录解压出对应的 so 文件并重新加载来解决大部分;这两种方法不能保证可以100%解决问题,但可以减少大部分问题(90%);

References

[1] loadLibrary动态库加载过程分析: http://gityuan.com/2017/03/26/load_library/ [2] Relinkder: https://github.com/KeepSafe/ReLinker

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 stringwu的互联网杂谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 so 加载过程
  • 2 问题分析
    • 2.1 问题
      • 2.2 分析1
        • 2.3 分析2
          • 2.4 分析3
          • 3 总结
            • References
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档