我们在市场上使用我们的应用程序的一些安卓手机上遇到了 java.lang.UnsatisfiedLinkError
问题。
问题描述:
static
{
System.loadLibrary("stlport_shared"); // C++ STL
System.loadLibrary("lib2");
System.loadLibrary("lib3");
}
在其中一个System.loadLibrary()
行中崩溃,并出现java.lang.UnsatisfiedLinkError
错误。
java.lang.UnsatisfiedLinkError: 无法从加载器 dalvik.system.PathClassLoader[dexPath=/data/app/app_id-2.apk,libraryPath=/data/app-lib/app_id-2] 中找到 stlport_shared 库,findLibrary 返回 null
解决方案
我们开始对所有安装进行一些自定义诊断,以检查是否将每个lib都解压缩到/data/data/app_id/lib
文件夹中。
PackageManager m = context.getPackageManager();
String s = context.getPackageName();
PackageInfo p;
p = m.getPackageInfo(s, 0);
s = p.applicationInfo.dataDir;
File appDir = new File(s);
long freeSpace = appDir.getFreeSpace();
File[] appDirList = appDir.listFiles();
int numberOfLibFiles = 0;
boolean subFilesLarger0 = true;
for (int i = 0; i < appDirList.length; i++) {
if(appDirList[i].getName().startsWith("lib")) {
File[] subFile = appDirList[i].listFiles(FileFilters.FilterDirs);
numberOfLibFiles = subFile.length;
for (int j = 0; j < subFile.length; j++) {
if(subFile[j].length() <= 0) {
subFilesLarger0 = false;
break;
}
}
}
}
在我们拥有的每台测试手机上,numberOfLibFiles == 3
并且subFilesLarger0 == true
。我们想测试所有库文件是否被正确地解压缩并且大小大于0字节。此外,我们还查看freeSpace
以查看可用的磁盘空间量。在屏幕底部的“设置”-->“应用程序”中可以找到与freeSpace
相同的内存量。我们采用这种方法的思路是,当磁盘上没有足够的可用空间时,安装程序可能会在解压缩APK时出现问题。
真实场景
根据诊断结果,一些设备在/data/data/app_id/lib
文件夹中没有全部3个库文件,但有很多可用空间。我想知道为什么错误消息正在寻找/data/app-lib/app_id-2
。我们所有的手机都将库文件存储在/data/data/app_id/lib
中。另外,System.loadLibrary()
应该在安装和加载库文件时使用一致的路径?如何知道操作系统正在查找哪个路径下的库文件?
问题
是否有人遇到安装本地库文件的问题?有哪些成功的解决方法?有没有在库文件不存在时仅从互联网上下载本地库文件并手动存储的经验?问题最初可能是由什么引起的?
编辑
我现在还有一个用户,在应用程序更新后遇到了这个问题。旧版本在他的手机上运行良好,但更新后似乎缺少了本地库文件。手动复制库文件也似乎会出问题。他使用的是未root的Android 4.x手机,没有自定义ROM。
编辑2-解决方案
经过两年的研究和努力,我们找到了一个对我们很有效的解决方案。我们将其开源: https://github.com/KeepSafe/ReLinker