Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing CPU/ABI to armeabi-v7a on Android

I have an Android app that uses some JNI code. Long story short (pun intended), it is nearly impossible to convert the JNI libraries to 64-bit as it would require a lot of changes. The code (both Java and JNI) works nicely on armeabi-v7a architecture.

The libraries are being loaded using loadLibrary. When I attempt to run my app on a Nexus 6, the app loads fine. As soon as loadLibrary is executed, the app crashes with the error described here.

The problem, as I understand it, is that when executing on Nexus 6, the app builds as arm64-8a. But the libraries are not built for arm64-8a (as the 64-bit version has issues I mentioned at start of the question).

My question is, can I force arm64-8a devices to also run armeabi-v7a code? How do I force my app apk to be armeabi-v7a so it is only 32-bit regardless of device?

like image 263
LNI Avatar asked May 16 '16 04:05

LNI


1 Answers

Yes, arm64-v8a devices can also run armeabi-v7a code.

When the APK is installed, the installer checks if the package contains libraries in the official directories, and marks the activity as 32 or 64 bit depending on the outcome.

If it finds libraries in lib/arm64-v8a within the APK (normally taken from the directory libs/arm64-v8a in the build directory), it will be marked as 64 bit, and will ignore all other directories. If it finds libraries in lib/armeabi-v7a or lib/armeabi in the APK, the process is marked as 32 bit. If there's no native libraries in any of these, the installer assumes that the application doesn't use native code at all and is free to run it in either mode, in practice in 64 bit mode.

Now if you do ship some, but not all, libraries in 64 bit mode, the process will be launched in 64 bit mode and will be unable to load the 32 bit libraries (which won't even be installed). In this case, you must avoid bundling any 64 bit libraries unless all of them are available.

Or you don't use the official libs directory but install your libraries some other way (e.g. by downloading them at runtime or keeping them in e.g. assets), the system has no idea that your process wants to run libraries in 32 bit mode (at which point it is too late to switch to the other mode). In these cases, make sure to include at least some dummy library in the normal/official way, in order to flag the application as 32 bit.

See https://stackoverflow.com/a/33919454/3115956, https://stackoverflow.com/a/27713998/3115956 and https://stackoverflow.com/a/35450911/3115956 for answers to similar issues.

like image 134
mstorsjo Avatar answered Sep 26 '22 10:09

mstorsjo