I have library project with precompiled so files. I want to minimize size so I want to use "armeabi" .so file for all arm abi's. (i need only arm code). To do this I put in jnilibs only the armeabi folder with the .so file.
The problem rises when i try to test this:
I created a demo app that uses my library project, the google play says i don't have a compatible device for this app.
Is it possible to use the same so file for all arm architectures and maintaining the size (in library project) ?
I don't care about preformance
Related
I'm currently working on two different xamarin forms projects which are kind of similar though. This means that they both have mostly similar functionalities + a lot of external dependencies are the same. But I just realized that the generated .apk files are very different in size. Upon analyzing both apks with the android studio apk analyzer I found out, that the main difference between both apks lies within the "lib" folder. While one apk only contains .so files the other (bigger) one contains a lot of .dll.so files. These cause the apk to be much bigger (40MB vs 75MB).
1.) Do you have any idea why there are dll.so files in one apk but not the other?
2.) Are these dll.so files needed?
3.) If not, is there a way to get rid of these?
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 library. On Android system, each CPU architecture corresponds to an ABI: armeabi, armeabi-v7a, x86, MIPs, arm64-v8a, MIPS64, x86_64.
For a mobile phone with a 64arm CPU, when it runs the app and enters libs to read the dynamic library file, it will check whether there is an arm64-v8a folder. If it didn't find arm64-v8a folder it will search for the armeabi-v7a folder and the armeabi folder, and then if the folder is not founded it will throw an exception.
I have a project with native libraries that I want to use, files with this format: lib<name>.so do get included into apk. But files with <name>.so format does not.
Is there a way to include the later type into apk in lib directory?
If not, is there a way to include the files into a directory inside apk, where I can load it from my native code?
The short answer is "no". The native binaries will only be packed into APK, and extracted to executable files upon installation, if their names follow the lib….so pattern.
Note that these libraries will be extracted to files according to the ABI of the target system. The installer does not check the actual properties of the file. The decision is based on the name of the folder under lib in the APK structure.
If you add the attribute extractNativeLibs=false to the application tag in AndroidManifest.xml of your APK, the installer (on Android Nougat and higher) will not extract the native libraries.
You can trick the system and have files that don't follow the above rule to the lib folder of APK, but there is very little sense in it, because they will never be extracted by the loader (it may also extract file gdbserver if the file is there).
The common practice is to put the arbitrary files in the assets folder of your APK, and extract them programmatically when the app runs for the first time after install. You cannot extract these files to the secured location where the usual native libraries go. You should not extract the native libraries to sdcard (e.g. getExternalFilesDir()), because the system may not allow execution of the files there, regardless of the execute access flag on the file. Make sure that you use the correct ABI flavour.
You can peek at the source code of Nougat native lib loader that can load native libraries from the APK without extraction, and use it to load your custom libraries directly from the assets folder of your APK.
How can I extract the type of architecture a certain APK was built for? I have to different APKs, one for 'x86' and the other for 'armeabi-v7a'.
I think you have .so files. While importing them, you need to classify your folders. So each releated .so files should go related folder that is named.
libs
arm
*lib.so
x86
*lib.so
I'm building a native C++ library for Android, for use with a Unity 3d project.
I want to build for arm and x86, so I set this in application.mk
APP_ABI := all
This gives me several seperate .so files. Unfortunately currently the way to include an native android library in a unity app is to add the library to the folder assets\Plugins\Android.
I can only put one file with the libraries name in that folder. So i can only have one of the .so files in there.
Is there any way of merging them into one file?
You can put multiple .so files, one for each architecture, into the Plugins/Assets folder, per the Unity documentation:
For specific Android platform (armv7, x86), the libraries (lib*.so) should be placed in the following:
Assets/Plugins/Android/libs/x86/
Assets/Plugins/Android/libs/armeabi-v7a/
Merging multiple architectures into a single .so can't be done on Linux.
That requires fat binrary support, and the FatELF project is now dead.
I am struggling with using Dropbox (Sync API) and Andengine in the same android app. Both are using native libraries and, as far as I know, Andengine is developed for ARMv7a and Dropbox for ARM systems. Running each part of the application on its own, everything works fine. However, combining both parts results in a: java.lang.UnsatisfiedLinkError: Couldn't load DropboxSync: findLibrary returned null.
It seems that only the armeabi-v7a folder is checked for the library as soon as this folder is present? However, the libDropboxSync.so is only located in the armeabi folder.
Everything is tested with a Nexus S running Android 4.1.2.
Thanks in advance,
Stefan
From $NDK/docs/CPU-ARCH-ABIS.html: if primary-abi is found secondary won't be scanned.
III.3. Automatic extraction of native code at install time:
-----------------------------------------------------------
When installing an application, the package manager service will scan
the .apk and look for any shared library of the form:
lib/<primary-abi>/lib<name>.so
If one is found, then it is copied under $APPDIR/lib/lib<name>.so,
where $APPDIR corresponds to the application's specific data directory.
If none is found, and a secondary ABI is defined, the service will
then scan for shared libraries of the form:
You can check this by;
$ adb shell getprop|grep abi
[ro.product.cpu.abi2]: [armeabi]
[ro.product.cpu.abi]: [armeabi-v7a]
as you can see primary abi is more specific then the secondary one.
Solution-wise you can move armv5 library under armv7-a. It should work, but it will be only visible to such devices under Google Play.
Check out the 3rd and 4th point
Within Android Studio, switch to the "project view".
From the libs directory in the downloaded SDK, drag dropbox-sync-sdk-android.jar into your project's app/libs directory.
Right-click on dropbox-sync-sdk-android.jar and choose "Add as library". Click "OK" on the dialog that appears.
Make a new directory in your project under app/src/main called jniLibs. From the SDK, drag armeabi, armeabi-v7a, mips, and x86 into
the new jniLibs directory.