Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NDK - multlib support using gradle

My question is directed towards native Android development for 64bit Android systems.

I am looking for a way to configure the support of 32bit compiled native libraries at a 64bit Android system using the gradle build system. The libraries the application should use are only available as 32bit build. It would be very time consuming and error prone to port these libraries to 64bit.

Hence, I want to configure gradle to deploy these prebuilt 32bit binaries and to use a 32bit version of the Android application as well.

The current configuration leads to the following error:

 E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: <application_name>, PID: 2170
    java.lang.UnsatisfiedLinkError: 
dalvik.system.PathClassLoader
[DexPathList[[zip file "/data/app/<application_name>/base.apk"],
nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]] 
enter code here`couldn't find "libmynativelibrary.so"
    at java.lang.Runtime.loadLibrary(Runtime.java:366)

It seems as though the PathClassLoader looks in the wrong directories. I checked the provided apk file and it is lacking the libraries. There is no lib folder inside the apk. The build system does not seam to include the 32bit libraries. Since there is only one prebuild version for armv7 these libraries are in app/src/main/jnilibs folder.

I have to add that this setup works perfectly for any 32bit Android system. I tried it with the emulator and a physical device before.

How should one activate the multiarch 32/64bit support using gradle? Or how is it possible to deploy a 32bit application to a 64bit Android system using Android Studio/gradle?

I searched the web and found one link concerning the topic, but it is referring to the older build system: https://source.android.com/source/64-bit-builds.html. I do not know how to adopt the description to gradle.

I am using Android Studio (Build: 141.1989493, June 6, 2015). The project/build.gradle is untouched. The app/build.gradle file looks like this:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "<application_name>"
        minSdkVersion 1
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                                                 'proguard-rules.pro'
        }
        debug {
            debuggable true
        }
    }

    productFlavors {
        armv7 {
            ndk {
                abiFilter "armeabi-v7a"
            }
        }
        fat
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}
like image 506
Matthias Scholz Avatar asked Jun 10 '15 16:06

Matthias Scholz


People also ask

Is NDK necessary for Android studio?

The Android Native Development Kit (NDK): a set of tools that allows you to use C and C++ code with Android. CMake: an external build tool that works alongside Gradle to build your native library. You do not need this component if you only plan to use ndk-build.

What is Android NDK side by side?

NDK (Side by side) is irrelevant for Android Gradle Plugin earlier than 3.5. However, the components available for download by SDK manager aren't customizable based on Android Gradle Plugin version so the side by side NDKs will appear.

How do I know if NDK is installed?

Open your Android Studio Preference (or "File->Settings") > Appearance & Behavior > System Settings > Android SDK. You can find the path to your SDK and NDK, which is in the same directory.


1 Answers

The concept of mulilib is only for projects that are part of an Android system build and you shouldn't set the android:multiarch option as you only have 32bit libs since this option is only for apps that are providing both 32 and 64bit libraries to other installed application.

64-bit Android systems support 32-bit applications directly. You only need to properly package your app, with your .so files inside lib/(armeabi-v7a,x86,...) of the APK, as for any Android devices.

At the install time, the libs of the architecture that is preferred by the device will be installed. ie: if there is no x86_64 folder, the x86 libs will be installed / if there is no arm64-v8a folder, the armeabi-v7a libs will be installed, and your app will run in 32-bit mode.

If you don't have anything under lib, that means Android Studio doesn't know about your .so files. By default it will look for them inside jniLibs/(armeabi-v7a,x86,...), hence you should place them there or change sourceSets.main.jniLibs.srcDir to the directory of your choice.

like image 115
ph0b Avatar answered Oct 19 '22 04:10

ph0b