Load native shared library from another Android application - android

I need to distribute an application (a player), which depends on a native library built for a given ARM version and extension (Tegra, Neon). This native library is quite large so I can’t distribute all its versions in one universal package. So I decided to split the application into one small universal .apk and more specialized .apks – plug-ins without any activities.
How can I access a specialized native shared library in the plug-in app from the main host application? Is it possible to use simply
System.loadLibrary("path_to_library");
If so, how can I get the path to that library?
How to solve this problem in case it is not possible?

System.loadLibrary() takes a library name and maps it to a full path somehow.
foo => libfoo.so
The system normally checks the apk itself and then usually /system/lib/
If you have a full path, use System.load()
In any case it will be a hassle to manage the location of your lib unless it's either in the apk or with all the system libs.
I'd just pack the specific lib with the apk.

Eight years later, the major concerns of the TS have been addressed: there are splits that can produce smaller APK for each ABI, there are app bundles that allow easier packaging, there are extensions that even allow to delay download of a native library until it is really needed by the app…
Still, the same technique to System.load("/data/data/{app-package}/lib/lib{library-name}.so") still works, and may be useful in some scenarios.

Related

Is there a way to use the Platstore's Dynamic Delivery to download the native libs (.so) at runtime after install?

As the question says, can I use the Dynamic delivery feature to deliver the .so files that my app uses after installation? My .so files are 15 MB in size and this causes the app's size to increase two-fold.
If not , is there any other way I can provide the native libs to the app during runtime? The Developer Program Content is pretty clear about this though:
An app distributed via Google Play may not modify, replace, or update itself using any method other than Google Play's update mechanism. Likewise, an app may not download executable code (e.g. dex, JAR, .so files) from a source other than Google Play. This restriction does not apply to code that runs in a virtual machine and has limited access to Android APIs (such as JavaScript in a webview or browser).
Here are some examples of common violations:
Apps or third party code (e.g., SDKs) that download executable code, such as dex files or native code, from a source other than Google Play.
Thank you for your help!!
Yes, you can create a dynamic feature module which can contain native libraries.
The feature module is just like an android library which can contain code, assets and other resources.

Optional shared library

I am developing an application that must be compatible with all Android device architectures. Also, some of these devices may have UHF reader capabilities that I want to exploit.
For these special devices, I have a shared library for the armeabi architecture. In devices with this architecture, the application works fine (whether they have UHF reader or not). However, for devices with other architectures, the application is not even installed, with an INSTALL_FAILED_NO_MATCHING_ABIS error.
I want to know if there is any way to make the library optional, so that devices of other architectures simply ignore it.
It would be ok if I could explicitly load the library (or not, depending on the architecture) using
System.loadLibrary("DeviceAPI");
but I don't know how to fix the installation problem. I want to avoid generating more than one APK.
Ok, this is surely not the best way to go, but it seems to work. I simply created a dummy shared library for every missing platform and renamed the .so files with the same name as my armeabi library file. The app installs now in every platform and I only have to catch the proper exceptions at initialization or check the device architecture.

Building an AOSP app that uses shared libraries

How could it be possible to build an AOSP app from source (using mma to build so there would only be the needed modules instead of a full system image) and have access to shared libraries?
I'm building LatinIME with some modifications.
As I wanted to easily install and debug, I changed the package name. Now I can easily install the app as user app but it can't access the .so files in system partition. If I try to install the app with original package name, it can't because of the old app installed.
library "/system/lib64/libjni_latinimegoogle.so" ("/system/lib64/libjni_latinimegoogle.so") needed or dlopened by "/system/lib64/libnativeloader.so" is not accessible for the namespace
The other way I could think of is to keep the package name as original but either create a flashable zip or copy the apk each time to system partition.
Is it possible to allow access to this file (or include it in the apk) or do I need to do this the hard way?
The easiest path is to have a copy of all needed non-public system native libraries in your APK, under lib/arm64-v8a or the other relevant ABI. libjni_latinimegoogle.so may depend on other libraries, and you must pack them with your APK, too. Make sure you use the correct versions of these libs. You can pull them from your system/lib64 via adb.
But replacing the APK in the system partition is a cleaner way to handle the situation. This does involve reboot each time, but I would probably choose this track, to avoid any possible behavioral differences between the system app and the user app.

Can I upload apks for multiple architectures into the Google Play store without using the android NDK?

I need to produce 2 apks, one for x86 and one for ARM. I do this with different versions of crosswalk, which internally uses cordova. All I need to do one the two projects are created is ./cordova/build --release and then sign the APK. The Google Play store docs mention a way of uploading both into a single app listing, but they assume I'm using the Android NDK, which I'm not. Will I need to start using it or is there another way to simply upload both apks?
Google does support posting of architechture-specific APKs: http://developer.android.com/google/play/publishing/multiple-apks.html. Note however that the documentation states, in bold:
we encourage you to develop and publish a single APK
So, if you take the single APK approach:
Just compile your native code into libraries (i.e. .so files) and place them in the following locations
<Project_Root>/app/src/main/jniLibs/armeabi/
and
<Project_Root>/app/src/main/jniLibs/x86/
The build process will package these in the appropriate manner so that your APK contains libs for both architectures. Then at runtime, Android will ensure that the architecture-appropriate library is loaded.
Note that the above assumes that you are using Gradle to build your APKs. If you are using the old ant-based build process, the locations are slightly different:
<Project_Root>/libs/armeabi/
and
<Project_Root>/libs/x86/

What's the difference between a regular Android APK and one included as part of a device's system image?

We have a manufacturer that wants to pre-install our application on their Android device. We sent them the APK and even though it installs fine when used by a user, it appears to not get installed correctly when included in the manufacturer's build image. FYI, our application uses the JNI layer and some libraries built with NDK. The exception we're seeing seems to indicate that the class loader cannot find the library and is unable to load it. They have verified that the library files are indeed present in the APK.
Since we dont make devices, its unclear why they are seeing this exception and what needs to be done differently when including a package as part of the Android build image.
Any Android folks here care to comment?
I have worked with pre-installed Android apps, that also uses library files, in my case jar files. I am assuming that you have added the appropriate lines to AndroidManifest.xml like <uses-library android:name..... I am also assuming that you have provided instruction on how to install your library files on handset, with instructions like adb push ... on the command prompt. If you havent, do provide them the instructions.
Another issue may be permissions, we had to get the library jar AND the permissions xml file installed, that may be the issue.
Also ensure that you are using the correct version of Android for testing. And if everything fails, ask them to send one of the handsets that is not working to you and you can then compare with the one in office and debug this. Good Luck, as all this can be pretty frustrating.
Besides moving the apk file into /system/app, you should ask the manufacturer to move the native libraries created by NDK (.so files) to /system/lib or the path specified by LD_LIBRARY_PATH.
Please refer to https://groups.google.com/d/topic/android-porting/r_Ao7_PWgKQ for more details.

Categories

Resources