Reputation: 1771
I have an android application which works on most of devices well. The application crashes on some devices because of
java.lang.UnsatisfiedLinkError: Couldn't load myjpegjni from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.oso.ono.app-2.apk,libraryPath=/data/data/com.oso.ono/lib]: findLibrary returned null
I have compiled jni source for all architectures(APP_ABI := all in Application.mk).
It crashes when I try to load library with System.loadLibrary("myjpegjni");
any ideas?
Upvotes: 3
Views: 2380
Reputation: 1393
You said you built for all ABI, but please double check that in the jniLibs folder has all sub folder: armeabi, armeabi-v7a, x86, mips... or at least it has folder with the same ABI with the device was crashed.
If they all exist, the ABI is matched. The problem maybe come from unpacking lib while installing your app.
You can try this for manually unpacking the lib:
public static int loadLibrary(Context context, String library){
try {
System.loadLibrary(library);
return 0;
} catch (UnsatisfiedLinkError ignored) {
ignored.printStackTrace();
}
File workaroundFile;
try {
workaroundFile = getWorkaroundLibFile(context, library);
if (!workaroundFile.exists()) {
unpackLibrary(context, library, workaroundFile);
}
try {
System.load(workaroundFile.getAbsolutePath());
return 1;
} catch (Throwable e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
public static File getWorkaroundLibFile(final Context context, final String library) throws PackageManager.NameNotFoundException {
final String libName = System.mapLibraryName(library);
return new File(context.getDir("my_libs", Context.MODE_PRIVATE), libName);
}
@TargetApi(Build.VERSION_CODES.DONUT)
private static void unpackLibrary(final Context context, final String library, final File outputFile) throws IOException {
ZipFile zipFile = null;
try {
final ApplicationInfo appInfo = context.getApplicationInfo();
zipFile = new ZipFile(new File(appInfo.sourceDir), ZipFile.OPEN_READ);
InputStream inputStream = null;
FileOutputStream fileOut = null;
try {
inputStream = getInputStreamFromApk(zipFile, library);
fileOut = new FileOutputStream(outputFile);
copyStream(inputStream, fileOut);
} finally {
closeSilently(inputStream);
closeSilently(fileOut);
}
if (Build.VERSION.SDK_INT >= 9) {
// Change permission to rwxr-xr-x
outputFile.setReadable(true, false);
outputFile.setExecutable(true, false);
outputFile.setWritable(true);
}
} finally {
try {
if (zipFile != null) {
zipFile.close();
}
} catch (IOException ignored) {}
}
}
private static void copyStream(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[4096];
while (true) {
int read = in.read(buf);
if (read == -1) {
break;
}
out.write(buf, 0, read);
}
}
private static void closeSilently(final Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException ignored) {}
}
Upvotes: 1
Reputation: 4400
Either your native library is not located in /data/data/com.oso.ono/lib or it is not called libmyjpegjni.so.
Upvotes: 0