1. What is CPU architecture and ABI? The Android system currently supports seven different CPU architectures: ARMv4, ARMv5, ARMv7 (since 2010), x86 (since 2011), MIPS (since 2012), ARMv8, MIPS64, and x86_64 (since 2014), each of which is associated with a corresponding ABI. The Application Binary Interface (ABI) defines how binary files (especially .so files) run on the corresponding system platform, from the instruction set used, memory alignment to the available system function libraries. On the Android system, each CPU architecture corresponds to an ABI: armeabi, armeabi-v7a, x86, mips, arm64-v8a, mips64, x86_64. 2. Why should we focus on .so files? If you use NDK in your project, it will generate .so files, so obviously you are already paying attention to it. If you only use Java language for coding, you may think that you don't need to pay attention to .so files because Java is cross-platform. But in fact, even if you only use Java language in your project, in many cases, you may not realize that the function library or engine library that your project depends on has embedded .so files and depends on different ABIs. For example, if you use RenderScript support library, OpenCV, Unity, android-gif-drawable, SQLCipher, etc. in your project, you have already included .so files in the generated APK file, and you need to pay attention to .so files. The ABI supported by an Android application depends on the .so file located in the lib/ABI directory in the APK, where the ABI may be one of the seven ABIs mentioned above. Native Libs Monitor is an application that can help us understand which .so files are used by the APK installed on the phone, and which libraries or frameworks the .so files come from. Of course, we can also decompile the APP ourselves to obtain this information, but it is relatively troublesome. Many devices support more than one ABI, for example, ARM64 and x86 devices can run both armeabi-v7a and armeabi binaries. But the best is to provide platform-specific binaries for the corresponding platform, in this case there is one less emulation layer at runtime (for example, a virtual layer emulating arm on x86 devices), which results in better performance (thanks to recent architecture updates, such as hardware fpu, more registers, better vectorization, etc.). We can get a list of ABIs supported by devices sorted by preference through Build.SUPPORTED_ABIS. But you should not read it from your application, because when the Android Package Manager installs the APK, it will automatically select the .so file precompiled for the corresponding system ABI in the APK package, if the .so file exists in the corresponding lib/ABI directory. 3. Where should the .so file be placed? It is easy to get confused about where the .so file should be placed or generated. Here is a summary:
4. When installing Apk, PackageManagerService selects the strategy for decompressing so files In the Android system, when we install the Apk file, the so files in the lib directory will be unpacked into the native library directory of the App, generally placed in the /data/data/package-name/lib directory. Depending on the system and CPU architecture, the copy strategy is also different. Improper configuration of the so file, such as when some Apps use third-party so files and only configure the so files for one CPU architecture, may cause adaptation problems for the App on some models. Android version so copy strategy Strategic issues 5. Suggestions for configuring so In response to these copy policy issues of the Android system, we have given some configuration suggestions for so: 5.1 For armeabi and armeabi-v7a ABI
5.2 For x86 Currently, in order to be compatible with arm instructions, the x86 models on the market basically have built-in libhoudini modules, that is, binary transcoding support. This module is responsible for converting ARM instructions into x86 instructions. Therefore, if you consider the size of the Apk package and can accept some performance loss, you can choose to delete the x86 library directory. The so library in the armeabi directory configured under x86 can also be loaded and used normally. 5.3 Targeting 64-bit ABI If the App developer intends to support 64-bit, then all 64-bit sos must be put in place. Otherwise, you can choose not to compile 64-bit sos separately and use all 32-bit sos. 64-bit models support the loading of 32-bit sos by default. For example, if the Apk uses a third-party so that only has 32-bit ABI sos, you can consider removing the 64-bit ABI subdirectory under the lib directory in the Apk to ensure that the Apk can be used normally after installation. 5. Android Studio configures abiFilters
This sentence means to specify the architecture that NDK needs to be compatible with, filter out all compatible packages except armeabi-v7a, and only leave one armeabi-v7a folder. Even if we do not specify other compatible frameworks, a filter is still needed. When we connect to multiple third-party libraries, it is likely that the third-party libraries are compatible with multiple platforms. For example, fresco is compatible with various platforms, so it creates directories for various compatible platforms. Because as long as this directory appears, the system will only look for .so files in this directory and will not traverse other directories, so the .so file cannot be found. 6. java.lang.UnsatisfiedLinkError There are many types of errors, which are classified as follows:
Cause: Apparently the root cause of the above crash is:
As for the second reason, it is obviously relatively easy to troubleshoot, and in development, such function calls must be tested at compile time and in debug mode, so the probability of this reason occurring is very small. The following are some of the reasons why "so cannot be loaded" leads to the above crashes: 6.1 Defects of the generated so A simple example: Crash stack:
Solution: Checking the original project Application.mk, I found APP_STL := gnustl_shared. The original solution used a shared library, which may not support all models. The problem was solved by using the static library gnustl_static instead. Correspondingly, in Android Studio, the shared library needs to be replaced with the static library gnustl_static. This type of problem about so compiled shared libraries needs to be checked.
The above example is just a simple example. When so is compiled and generated, it may cause an UnsatisfiedLinkError crash due to reasons such as not considering the model matching of the shared library. Secondly, 64-bit and 32-bit system architecture problems may also cause UnsatisfiedLinkError crashes. 6.2 No space on the mobile device When so is generated correctly, the corresponding library will be generated according to the set support so library framework. In the Android system, when we install the Apk file, the so files in the lib directory will be decompressed to the native library directory of the App, generally in the /data/data/package-name/lib directory. When preparing to load the native layer so, although there is a corresponding so file in the Apk, the mobile device does not have enough space to load the so, resulting in a loading failure and the above crash. 6.3 so configuration error If the so file is generated correctly and there is enough space on the phone, then as mentioned above, in the Android system, when we install the Apk file, the so file in the lib directory will be unzipped to the native library directory of the App, generally in the /data/data/package-name/lib directory. However, depending on the system and CPU architecture, the copy strategy is also different. If the so file is configured incorrectly, for example, when some Apps use third-party so files, only one type of CPU architecture is configured, it may cause adaptation problems for the App on some models, resulting in the above-mentioned crash. 6.4 Android PackageManager installation problem The user installed an Apk installation package that does not match the mobile phone's CPU architecture, or the so file was not released correctly during the App upgrade process for various reasons. This problem can be solved using ReLinker. Using ReLinker is very simple.
Just replace the standard one.
|
<<: A comprehensive summary of design anomalies and how to handle them
>>: Super comprehensive! Comparison of design differences between Android apps and iOS apps
"He He", "Jiu Jiu" and "...
It’s the Spring Festival travel season again, and...
Let the "most beautiful highway" become...
The user scale of private domain traffic is one o...
The Food and Agriculture Organization of the Unit...
Around 3:50 pm on January 9, two Chinese female t...
Tutorial on how to make money with movie ticket c...
Currently, Internet marketing has become the main...
Sichuan Diverse landscapes and colorful cultures ...
Ford recently said that the cumulative orders for...
【51CTO Translation】The screen is so small, the ap...
Yesterday we talked about Facebook changing its n...
Double Eleven has just passed and Double Twelve i...
Today is the 27th National Safety Education Day f...
The 13th and 14th Guike Xianyu Project Practice C...