Android 4.X 系统加载 so 失败的原因分析
1 so 加载过程
so 加载的过程可以参考小米的系统工程师的文章loadLibrary动态库加载过程分析
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
。但我们的 so
的 crash
明显是不属于这种情况的,因为我们是通过 System.load()
方法加载完 so
文件后,就调用相关的方法,这时内存肯定是还在的。在分析了一系列可能的原因后,怀疑这个crash
是因为应用安装时解压出来的 so
文件是损坏的,因此我们尝试在第一次发生这个crash
时,将这个crash
catch
住,然后在 catch
块将原来目录下的 so
文件删除掉,并重新从应用的安装目录解压出对应的so
文件放到原来的目录,并加了相关的统计来验证。so
的加载用了 Relinkder。相关的简化版本代码如下:
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 的解决方法后,我们的 so
的 java.lang.unsatisfiedlinkerror native method not found
大部分消失了。理论上使用过一次重新解压so
文件后,这个用户在下一次升级前都应该不会再发生了类似的 crash
了,但我们的统计数据发现,有些用户每一次启动都需要进入catch
块来避免crash
,而每次都可以通过 reload
来正常使用我们的应用,这至今还是个迷,还没有想明白是什么情况会导致这个问题?手机的存储有问题?但其他的so
又没有这个问题。希望如果有同行解决过类似的问题的,指点一下。
3 总结
Android 4.X 系统加载 so 后,出现 java.lang.unsatisfiedlinkerror native method not found
的crash
的原因除了网上所说的 不存在这个so 和 方法名有问题(商用的应用应该不会有这个问题的)外,还有两个原因:
- so 加载进系统的内存被系统由于资紧张而回收了,这种情况下直接再
load
一下so
文件就可以解决大部分; - so 文件有问题,这种情况下,可以通过重新从应用安装目录解压出对应的
so
文件并重新加载来解决大部分;
这两种方法不能保证可以100%解决问题,但可以减少大部分问题(90%);
Android 4.X 系统加载 so 失败的原因分析的更多相关文章
- React Native 断点调试 跨域资源加载出错问题的原因分析
写在前面 ————如果从头开始看还没解决,试试文章最后的绝招 闲来无事,折腾了一下React Native,相比之前,开发体验好了不少.但在真机断点调试那里遇到了跨域资源加载出错的问题,一番探索总算解 ...
- H5:加载原理,慢加载和卡顿原因分析,
前端H5工作原理: 请求和显示原理 H5页面卡顿原因分析: 1.动画太多:渲染重绘占用GPU 2.页面操作导致重绘频繁 3.页面元素复杂:资源类标签太多(图像/视频/dom树太长) 4.内置webvi ...
- RequireJS首次加载偶尔失败
现象:第一次加载JS文件,首次加载偶尔失败: 原因:require(['jquery', 'operamasks', 'zTree', 'jQueryCookie'],中前后引用同步加载: 解决方式: ...
- Android系统加载Apk文件的时机和流程分析(1)--Android 4.4.4 r1的源码
本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80982869 Android系统在启动时安装应用程序的过程,这些应用程序安装好之 ...
- Android 的 so 文件加载机制
本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 最近碰到一些 so 文件问题,顺便将相关知识点梳理一下. 提问 本文的结论是跟着 System.loadlibrary() 一层层源 ...
- Android中一张图片加载后所占用内存大小的获取与测试
Android程序中一旦加载的图片比较多,就有可能出现Out of Memory而导致程序崩溃.这个一方面是因为Android系统本身对于每个单独的进程有内存大小的限制(有16M,64M,128M,2 ...
- Android中的动态加载机制
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- java攻城狮之路(Android篇)--widget_webview_metadata_popupwindow_tabhost_分页加载数据_菜单
一.widget:桌面小控件1 写一个类extends AppWidgetProvider 2 在清单文件件中注册: <receiver android:name=".ExampleA ...
- Android中的Glide加载图片
注意:在Android Studio的项目的build.gradle中添加: compile 'com.github.bumptech.glide:glide:3.6.1' 然后同步一下 目录: 使用 ...
随机推荐
- MySQL“被动”性能优化汇总!
年少不知优化苦,遇坑方知优化难. --村口王大爷 本文内容导图如下: 我之前有很多文章都在讲性能优化的问题,比如下面这些: <switch 的性能提升了 3 倍,我只用了这一招!> < ...
- python3.x与2.x中print输出不换行
python3.x: print(i,end=' ') 循环输出: ... ------------------------- print(i,end='!') 循环输出:!!!... end=单引号 ...
- 基于token的会话保持机制
session简介 做过Web开发的程序员应该对Session都比较熟悉,Session是一块保存在服务器端的内存空间,一般用于保存用户的会话信息. 用户通过用户名和密码登陆成功之后,服务器端程序会在 ...
- NOIP真题索引
NOIP真题索引 NOIP2019 Day 1 格雷码 括号树 树上的数 Day 2 Emiya 家今天的饭 划分 树的重心 NOIP2018 Day 1 铺设道路 货币系统 赛道修建 Day 2 旅 ...
- STL函数库的应用第四弹——全排列(+浅谈骗分策略)
因为基础算法快学完了,图论又太难(我太蒻了),想慢慢学. 所以暂时不写关于算法的博客了,但又因为更新博客的需要,会多写写关于STL的博客. (毕竟STL函数库还是很香的(手动滑稽)) 请出今天主角:S ...
- put数据到topic
基于python3.6 # -*-coding:utf-8 *- __author__ = 'lc_yy' from pykafka import KafkaClient import logging ...
- 【小白学AI】随机森林 全解 (从bagging到variance)
文章转自公众号[机器学习炼丹术],关注回复"炼丹"即可获得海量免费学习资料哦! 目录 1 随机森林 2 bagging 3 神秘的63.2% 4 随机森林 vs bagging 5 ...
- JavaScript设计模式之命令模式【命令解耦】
在讲解命令模式之前我们先来了解一个生活中的命令模式场景: 场景1: 医院看病抓药: 当你因为肾虚到医院看医生,医生一番操作之后得出结论:要吃个疗程[夏桑菊].[小柴胡](药名纯属虚构,真的肾虚就找医生 ...
- CSS实现大数据热点波纹图
CSS实现大数据热点波纹图 实现效果: 涉及知识点: 定位 盒子阴影 动画 思想:以3道波纹为例.首先使用一个div盒子作为圆心,然后每道波纹作为一个div.4个盒子均使用定位属性定位到圆心.然后设置 ...
- Python脚本实现在cmd执行相关命令
通过Python脚本实现,在cmd命令执行文件的cp(复制).rm(删除).rename(重命名).move(文件移动).mkdir(创建目录) cmd执行命令格式:python xxx.py 用户名 ...