I am writing a game, and I have huge native library, I am trying to load my native library in my main activity like
static {
try {
System.loadLibrary("mylib");
} catch (UnsatisfiedLinkError e) {
Log.d(TAG, "Unsatisfied Link error: " + e.toString());
}
}
I have tested this code on many devices in house, I don't get this error. but from my published I do get logs with "Caused by: java.lang.UnsatisfiedLinkError: Cannot load library". NOTE: This crash is not universal, only few people are getting this crash
More Info on crash is : load_segments: 68 failed to map segment from mylib.so
Considering that your app works correctly on most of the devices and only sometimes gives you the error, it's safe to assume that the library is packaged correctly in the APK and that its size/memory footprint is also acceptable.
As such, I'll go on the whim and suggest that the problem is with the build/compile architecture of the library. Most newer Android devices use ARM7 processor. It's quite likely that your library is compiled against ARM7 architecture as well. Some older devices, especially those running Android 2.3, use ARM6 processor (I have one such device that I use for testing - LG GT540 running Android 2.3.3), which is not forward-compatible with ARM7 architecture. I have seen a crash with error similar to the one you indicated (load_segments: 68 failed to map segment from mylib.so) when I attempted to run an app designed for ARM7 on my old ARM6 phone.
There are three ways of going around this issue:
Compile the library against both architectures and include two separate .so files into the apk. Then at runtime determine the type of processor and load the correct one. Frankly, I don't know if this is even possible.
Create two separate apk files - one for ARM6 and one for ARM7 - then use filters in the manifest to specify the corresponding architecture. You can upload both of them to google play for the same app - and filters in the manifest will control which one is downloaded to which device.
Only support ARM7 architecture by specifying device requirements in your manifest. You will loose some customer audience, but will have less work for yourself maintaining the two versions of the app.
EDIT: According to NDK documentation, it can produce multiple libraries for different architectures in one go. You can control specifically which CPUs you want to target by adding the following line into the Application.mk
file:
APP_ABI := arch1 arch2 arch3 ...
for example,
APP_ABI := armeabi armeabi-v7a mips
Then the build process will create different versions of the native library. These versions will need to be placed in the final apk in directory
lib/<abi>/lib<name>.so
where is the name of the architecture. You will then load the library with
System.loadLibrary("<name>");
Alternatively you can build separate apk files for each architecture then use multi-apk functionality on google play.
You can find all the information on architecture targeting in file CPU-ARCH-ABIS.html
file in the docs
subdirectory of the NDK.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With