user2022581 user2022581 - 5 months ago 52
Android Question

How to build single APK with Android NDK and Gradle

I am working on a new android app using OpenCV (C++ not Java) and I am new to both opencv and the NDK. I have it building (and running) succesfully using the Gradle file below and in Android Studio I can select a variant and hit build (e.g. x86).

I have 2 questions:


  1. Is there a way I can have a variant that builds an APK supporting all architectures? (I know file size will be bigger)

  2. Can i achieve a build without specifying all the same libs for each variant. Is there any way I can make the build system just pick up the libraries each time since they are all inside the project and organised by architecture name?

    apply plugin: 'com.android.application'

    android {
    compileSdkVersion 21
    buildToolsVersion "21.0.0"

    defaultConfig {
    applicationId "uk.co.xxx.androidcppimagereader"
    minSdkVersion 17
    targetSdkVersion 21
    versionCode 1
    versionName "1.0"
    }

    def libsDir = projectDir.path + "/libs/"

    productFlavors {
    x86 {
    versionCode Integer.parseInt("3" + defaultConfig.versionCode)
    ndk {
    abiFilter "x86"
    moduleName "Processing"
    stl "gnustl_static"
    cFlags "-I/opt/local/include/opencv -I/opt/local/include"
    ldLibs libsDir + "x86/libopencv_core.a"
    ldLibs libsDir + "x86/libopencv_ts.a"
    ldLibs libsDir + "x86/libopencv_contrib.a"
    ldLibs libsDir + "x86/libopencv_ml.a"
    ldLibs libsDir + "x86/libopencv_java.so"
    ldLibs "log"
    ldLibs "z", "jnigraphics"
    }
    }
    armv7 {
    versionCode Integer.parseInt("2" + defaultConfig.versionCode)
    ndk {
    abiFilter "armeabi-v7a"
    moduleName "Processing"
    stl "gnustl_static"
    cFlags "-I/opt/local/include/opencv -I/opt/local/include"
    ldLibs libsDir + "armeabi-v7a/libopencv_core.a"
    ldLibs libsDir + "armeabi-v7a/libopencv_ts.a"
    ldLibs libsDir + "armeabi-v7a/libopencv_contrib.a"
    ldLibs libsDir + "armeabi-v7a/libopencv_ml.a"
    ldLibs libsDir + "armeabi-v7a/libopencv_java.so"
    ldLibs "log"
    ldLibs "z", "jnigraphics"
    }
    }
    arm {
    versionCode Integer.parseInt("1" + defaultConfig.versionCode)
    ndk {
    abiFilter "armeabi"
    moduleName "Processing"
    stl "gnustl_static"
    cFlags "-I/opt/local/include/opencv -I/opt/local/include"
    ldLibs libsDir + "armeabi/libopencv_core.a"
    ldLibs libsDir + "armeabi/libopencv_ts.a"
    ldLibs libsDir + "armeabi/libopencv_contrib.a"
    ldLibs libsDir + "armeabi/libopencv_ml.a"
    ldLibs libsDir + "armeabi/libopencv_java.so"
    ldLibs "log"
    ldLibs "z", "jnigraphics"
    }
    }

    }

    buildTypes {
    release {
    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    }
    }

    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    }


G3M G3M
Answer

Use the keyword "fat" after you have defined all architectures that you plan to include in your apk in the build.gradle file as highlighted in the code below . This will build a FAT binary. Watch this video for more details https://www.youtube.com/watch?v=kFtxo7rr2HQ

arm {
    versionCode Integer.parseInt("1" + defaultConfig.versionCode)
    ndk {
        abiFilter "armeabi"
        moduleName "Processing"
        stl "gnustl_static"
        cFlags "-I/opt/local/include/opencv -I/opt/local/include"
        ldLibs libsDir + "armeabi/libopencv_core.a"
        ldLibs libsDir + "armeabi/libopencv_ts.a"
        ldLibs libsDir + "armeabi/libopencv_contrib.a"
        ldLibs libsDir + "armeabi/libopencv_ml.a"
        ldLibs libsDir + "armeabi/libopencv_java.so"
        ldLibs "log"
        ldLibs "z",  "jnigraphics"
    }
  **fat**
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}