Bugtags V1.2.7 introduced the NDK so library, which, when integrated, encountered different so libraries packaged to the APK, installed on some machines, and failed to java.lang.UnsatisfiedLinkError
load.
To this end, a deep look at the principle, and give a solution.
Principle
The Android system is essentially a transformed Linux system. As early as the Android system only supported ARMV5 CPU architecture, with the development of Android system, added ARMv7, x86 (+), MIPS (+), ARMV8, MIPS64 and x86_64 (2014) 。
Each CPU architecture defines an ABI (application binary Interface), and the ABI determines how the binaries interact with the system.
In general, you don't need to pay attention to these things. When you use a third-party library with the so library in your APP, or use the NDK yourself to do something, you need to read the next tutorial carefully.
NDK so supports different CPU architectures
When you use the NDK to develop so libraries that contain C + + code, you can choose the output to support the following ABI CPU architectures:
armeabiarmeabiv7aarm64v8ax86x86_64mipsmips64
Bugtags's NDK library supports all CPU architectures as above:
But not everyone's developers provide an NDK library that supports all CPU architectures:
The library provided by the developer above only supports Armeabi.
In fact, in general, there is no problem, x86 equipment, will also be compatible with Armeabi so library.
Merge package into APK
Without any setup, the Android build system merges the so libraries from different developers into the APK compression package.
├── AndroidManifest.xml├── classes.dex├── lib│ ├── arm64-v8a│ │ └── libBugtags.so│ ├── armeabi│ │ ├── libhyphenate.so│ │ └── libBugtags.so│ ├── armeabi-v7a│ │ └── libBugtags.so│ ├── mips│ │ └── libBugtags.so│ ├── mips64│ │ └── libBugtags.so│ ├── x86│ │ └── libBugtags.so│ └── x86_64│ └── libBugtags.so├── res
System Installation APK
According to the official Ndk-abi documentation, when installing an APK, the Android system will consider the current device's CPU architecture and configuration (called the so-called Primary-abi and Secondary-abi) and go to the corresponding folder of the APK file to find the so library.
Assuming that the current device is a x86 machine, it takes precedence to find the so library under the Lib/x86 folder:
lib/<primary-abi>/lib<name>.so
If it is not found and Secondary-abi is defined, go to the following folder to find:
lib/<secondary-abi>/lib<name>.so
If found, copy the file to the following folder in the APK installation directory:
/lib/lib<name>.so
The corresponding so is not found, the installation is normal, but when the so is used at runtime, it crashes.
Here's the problem.
Maybe you have found the problem when an APK is in this situation:
├── AndroidManifest.xml├── classes.dex├── lib│ ├── arm64-v8a│ │ └── libBugtags.so│ ├── armeabi│ │ ├── libhyphenate.so│ │ └── libBugtags.so│ ├── armeabi-v7a│ │ └── libBugtags.so│ ├── mips│ │ └── libBugtags.so│ ├── mips64│ │ └── libBugtags.so│ ├── x86│ │ └── libBugtags.so│ └── x86_64│ └── libBugtags.so├── res
At the same time, the APK is installed on a x86 device, the above search process will fail, run, will appear the following error:
D/xxx (10674): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/xxx-2/base.apk"],nativeLibraryDirectories=[/data/app/xxx-2/lib/x86, /vendor/lib, /system/lib]]] couldn‘t find "libirdna_sdk.so"D/xxx (10674): at java.lang.Runtime.loadLibrary(Runtime.java:366)
Here, the author is a bit puzzling, since in the x86 folder can not find, should go to Armeabi folder automatically find Ah, here to leave a TODO, need to next to confirm whether it is some machine reason.
Solution Guidelines
NDK so developers should follow a guideline: Support all platforms, or they will screw up your users.
NDK so users should follow a guideline: either support all platforms or do not support them.
However, it backfired, for a variety of reasons (legacy so, chip market share, APK packet size, etc.), not everyone follows this principle.
Compromise Android Studio
- In the Android Gradle plugin, the ABI can be filtered using the following methods:
android { ... defaultConfig { ... ndk { // 设置支持的 SO 库构架,注意这里要根据你的实际情况来设置 abiFilters ‘armeabi‘// ‘armeabi-v7a‘, ‘arm64-v8a‘, ‘x86‘, ‘x86_64‘, ‘mips‘, ‘mips64‘ } }}
Key line:
abiFilters ‘armeabi‘// ‘armeabi-v7a‘, ‘arm64-v8a‘, ‘x86‘, ‘x86_64‘, ‘mips‘, ‘mips64‘
Depending on the architecture that is supported by the so library used in your APP, you can make the specific settings. The final output of the APK will contain the ABI of your choice.
As previously cited, only Armeabi should be allowed.
- If you add "Abifilter" to Android Studio, the following prompt appears:
NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin
The Gradle.properties file in the project root directory is added:
android.useDeprecatedNdk=true
Eclipse
In Eclipse, you need to manually control the contents of this folder in your project:
To achieve the above principles, so that the different structures of the equipment to operate normally.
Reference documents
What are you should know? So files
What you need to know about Android's. so file)
ABI Management
?
The ABI architecture selection in the development and use of NDK so library