The early Android system almost only supported the ARMV5 CPU architecture, do you know how many of these are supported today? 7 kinds.
The Android system now supports the following seven different CPU architectures: ARMV5. ARMV7 (since 2010), x86 (from 2011 onwards), MIPS (from 2012 onwards), Armv8,mips64 and x86_64 (from 2014), each of which is associated with a corresponding ABI.
The Application Binary interface (application binary Interface) defines how binary files (especially. so files) are executed on the appropriate system platform. From the instruction set used, the memory is aligned to the available system functions library.
On the Android system. Each CPU architecture corresponds to a abi:armeabi,armeabi-v7a,x86. Mips,arm64-v8a,mips64,x86_64.
1. Why you need to focus on. so files
Assuming that the NDK is used in the project, it will generate. so files, so obviously you are already watching it. Assuming that you are coding only in the Java language, you may be thinking that you do not need to pay attention to the. So file, because Java is cross-platform.
But in fact, even if you are only using the Java language in your project, in many cases, you may not be aware that the libraries or libraries that are dependent on the project are embedded in the. so file and rely on different ABI.
For example, the project uses the Renderscript support library, OpenCV. Unity,android-gif-drawable,sqlcipher, etc., you have already included the. So file in the generated apk file. And you need to focus on the. so file.
The ABI supported by the Android app depends on the. So file in the Lib/abi folder in the APK. The ABI may be one of the seven types of Abi mentioned above.
Native Libs Monitor This app can help us understand which. so files are used by the APK installed on the phone, and which libraries or frameworks the. so file originates from.
Of course. We are also able to decompile the app itself to get this information, but it's a bit more cumbersome.
Very many devices support more than one ABI. For example, ARM64 and x86 devices can also execute armeabi-v7a and Armeabi binary packages at the same time.
However, it is best to provide a platform-specific binary package for a particular platform. In this case, a simulation layer (such as the virtual layer on the x86 device simulating arm) is missing, resulting in better performance (thanks to recent architecture updates, such as hardware FPU. A lot of other registers, better vectorization, etc.).
We are able to get a list of ABI supported by preference-based devices via Build.supported_abis. But you should not read it from your application, since Android Package Manager installs the APK, it chooses the APK package to pre-compile the. so file for the corresponding system ABI, assuming that the. so file exists in the corresponding Lib/abi folder.
where there may be an error in 2.APP
There is an important law that is simple but not well known when working with. so files.
You should provide as much as possible the. so files optimized for each ABI, but they are all supported. Either is not supported: You should not mix the use. You should provide a corresponding. So file for each Abi folder.
When an app is installed on the device. Only the CPU architecture supported by the device corresponds to the. So file will be installed.
On the x86 device, the Libs/x86 folder assumes that the. so file is present. will be installed, assuming it does not exist, the. So file in the armeabi-v7a is selected. If it does not exist, select the. so file in the Armeabi folder (because the x86 device also supports armeabi-v7a and Armeabi).
3. Other places may also be wrong
When you introduce a. So file, it not only affects the CPU architecture. I can see a number of common errors from other developers, most of which are "Unsatisfiedlinkerror", "dlopen:failed" and other types of crash or low performance:
. So files compiled with the ANDROID-21 platform version number are executed on android-15 devices
When using the NDK. You may be inclined to use the latest compilation platform, but this is actually wrong, because the NDK platform is not back-compatible, but forward-compatible. It is recommended to use the Minsdkversion appropriate compilation platform for the app.
This also means that when you introduce a precompiled. So file, you need to check the version number of the platform that it was compiled with.
4. Mixing. So files that are compiled with different C + + executions
. So files can depend on different C + + executions, statically compiled or dynamically loaded. Mixing C + + execution with different version numbers can lead to a lot of strange crash that should be avoided.
As a rule of thumb. When there is only one. So file, it is no problem to statically compile C + + execution, otherwise when there are multiple. so files. All. So files should be dynamically linked to the same C + + execution time.
This means that when a new precompiled. So file is introduced, and there are other. So files in the project. We need to first confirm that the C + + execution of the newly introduced. So file is consistent with the. So file that already exists.
5. No corresponding. So files are provided for each supported CPU architecture
This has been said in the previous article, but you should really pay special attention to it, because it could happen without realizing it at all.
For example: Your app supports armeabi-v7a and x86 architectures. Then a library dependency was added using Android studio, which includes. so files and supports many other CPU architectures, such as the New Android-gif-drawable library:
compile ‘pl.droidsonroids.gif:android-gif-drawable:1.1.+’
When we publish our app, we'll find that it crash on some devices, such as Galaxy S6, and can finally find that only the. so file in the 64-bit folder is installed into the phone.
WORKAROUND: Compile our. So file again to support missing Abis, or set
ndk.abiFilters
Displays the specified supported Abis.
The last point: Suppose you are an SDK provider, but the library of functions provided does not support all abis. Then you will screw up your users, because the abis they can support will only be less than what you provide.
put the. So file in the wrong place
We tend to be very easy on. So files should be placed in or generated to be confused, here is a summary:
- The Android Studio project is placed in the Jnilibs/abi folder (and can of course be specified by setting the Jnilibs.srcdir property in the Build.gradle file)
- eclipse project is placed in the Libs/abi folder (this is also the folder where the Ndk-build command generates. So files by default)
- aar in the Jni/abi folder (. So files are actively included in the APK that references the AAR compression pack)
- Finally the Lib/abi folder in the apk file
- via Packagemanager after installation, in a system smaller than Android 5.0. The so file is located in the app's Nativelibrarypath folder, and the. So file is located in the app's Nativelibraryrootdir/cpu_arch folder on systems greater than or equal to Android 5.0.
simply provide a. So file for the Armeabi architecture and ignore the other Abis
All X86/X86_64/ARMEABI-V7A/ARM64-V8A devices support the. So file for the Armeabi architecture. So it seems that removing other abis. So files is a good technique to reduce the size of the APK. But not really: it doesn't just affect the performance and compatibility of the library.
The x86 device is capable of performing arm type function libraries very well. But there is no guarantee that 100% does not occur crash, especially for old equipment. 64-bit devices (arm64-v8a, x86_64, MIPS64) can execute 32-bit libraries, but in 32-bit mode, the art and Android components of the 32-bit version number are executed on 64-bit platforms. The performance that is optimized for 64 bits is lost (ART. Webview,media, etc.).
To reduce the size of the APK package is a false excuse. Since you can also choose to upload the APK with the specified ABI version number in the app market, the APK that generates different ABI version numbers can be configured in Build.gradle such as the following:
Android { ... Splits { Abi { enable true reset () include ' x86 ', ' x86_64 ', ' armeabi-v7a ', ' arm64-v8a '//select ABIs to B Uild APKs for universalapk true//generate a additional APK that contains all the ABIs } } //map for th E version code project.ext.versionCodes = [' Armeabi ': 1, ' armeabi-v7a ': 2, ' arm64-v8a ': 3, ' MIPS ': 5, ' Mips64 ': 6, ' X "8, ' x86_64 ': 9] Android.applicationVariants.all {variant--/ /Assign different version code for each O Utput Variant.outputs.each {output, output.versioncodeoverride = project.ext.versionCodes.get (Output.getfilter (Com.android.build.OutputFile.ABI), 0) * 1000000 + Android.defaultConfig.versionCode } } }
What you need to know about your. So file on Android