We're experiencing a java.lang.UnsatisfiedLinkError
on some of the Android phones that are using our app in the market.
Problem description:
static
{
System.loadLibrary("stlport_shared"); // C++ STL
System.loadLibrary("lib2");
System.loadLibrary("lib3");
}
Crashes the app in on of the System.loadLibrary()
lines with a java.lang.UnsatisfiedLinkError
.
java.lang.UnsatisfiedLinkError: Couldn't load stlport_shared from loader dalvik.system.PathClassLoader[dexPath=/data/app/app_id-2.apk,libraryPath=/data/app-lib/app_id-2]: findLibrary returned null
Solution approach
We started running some custom diagnostics on all our installs to check if every lib is unpacked in the /data/data/app_id/lib
folder.
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;
}
}
}
}
On every test phone that we have numberOfLibFiles == 3
and subFilesLarger0 == true
. We wanted to test if all libs are unpacked properly and are larger then 0 byte. In addition we're looking at freeSpace
to see how much disk space is available. freeSpace
matches the amount of memory that you can find in Settings --> Applications at the bottom of the screen. The thinking behind this approach was that when there is not enough space on the disk available that the installer might have problems unpacking the APK.
Real world scenario
Looking at the diagnostics, some of the devices out there do NOT have all 3 libs in the /data/data/app_id/lib
folder but have plenty of free space. I'm wondering why the error message is looking for /data/app-lib/app_id-2
. All our phones store their libs in /data/data/app_id/lib
. Also the System.loadLibrary()
should use a consistent path across installation and loading the libs? How can I know where the OS is looking for the libs?
Question
Anyone experiencing problems with installing native libs? What work arounds have been successful? Any experience with just downloading native libs over the internet when they are not existent and storing them manually? What could cause the problem in the first place?
EDIT
I now also have a user who runs into this problem after an application update. The previous version worked fine on his phone, an after an update the native libs seem missing. Copying the libs manually seem to cause trouble as well. He is on android 4.x with a non rooted phone without custom ROM.
EDIT 2 - Solution
After 2 years of spending time on this problem. We came up with a solution that works well for us now. We open sourced it: https://github.com/KeepSafe/ReLinker