How can I package different *.so files for different Build flavors?

how to open so file in android studio
how to use so file in android studio
how to generate so file in android studio
android build variants vs flavors
ndk in build gradle
android mk build gradle
shared library android studio
externalnativebuild abifilters

I have some pre-build *.so files for different build flavors like

arm64-v8a, armeabi-v7a, x86, x86_64,
and these files are of android third party library. When I run the project all these *.so files are packaging in apk. But here my question is that how to package different *.SO files in different apks? can you please give build.gradle script for this. any help will be appreciated? Thank you. Sorry for my poor english.

my library.gradle is

apply plugin: 'com.android.library'

import com.android.builder.core.DefaultManifestParser

android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion

sourceSets {
    main {
        jni.srcDirs = []
        // Prevent gradle from building native code with ndk; we have our own Makefile for it.
        jniLibs.srcDirs = ['jni/libs', 'jni/loader/libs', 'private_libs/libs']
        // Where generated .so files are placed.
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        renderscript.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    }
}

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

// Make per-variant version code
libraryVariants.all { variant ->
    def manifestParser = new DefaultManifestParser(android.sourceSets.main.manifest.srcFile)
    // get the version code of each flavor
    def version = manifestParser.getVersionName()
    //Custom APK name
    variant.outputs.all { output ->
        if (outputFileName != null && outputFileName.endsWith('.aar')) {
            outputFileName = "lib-${version}.aar"
        }
    }
}
}

class BuildNative extends Exec {}

tasks.withType(BuildNative) {
/*
Properties set for Android Studio own shell.
when you run gradlew from cli, OS shell env variables will be used

To be able to build from Android Studio, you have to set ndk.dir & sdk.dir
properties in local.properties in the root folder, like this (for example):
sdk.dir=/home/<username>/SDK/android-sdk-linux
ndk.dir=/home/<username>/SDK/android-ndk-r10b
 */
if (System.getenv('ANDROID_SDK') == null || System.getenv('ANDROID_NDK') == null) {
    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())
    environment 'ANDROID_NDK', properties.getProperty('ndk.dir')
    environment 'ANDROID_SDK', properties.getProperty('sdk.dir')
}
workingDir '..'
commandLine './compile-libvlc.sh'
}

task buildDebugARMv7(type: BuildNative) {
args('-a', "armeabi-v7a")
}
task buildDebugARM64(type: BuildNative) {
args('-a', "arm64-v8a")
}
task buildDebugx86(type: BuildNative) {
args('-a', "x86")
}
task buildDebugx86_64(type: BuildNative) {
args('-a', "x86_64")
}
task buildDebugMIPS(type: BuildNative) {
args('-a', "mips")
}
task buildDebugMIPS64(type: BuildNative) {
args('-a', "mips64")
}

task generateSources(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}

clean {
// delete 'build', /*'jni/libs',*/ 'jni/obj'
}

dependencies {
api "com.android.support:support-annotations:$rootProject.ext.appCompatVersion"
api "com.android.support:support-v4:$rootProject.ext.appCompatVersion"
}

and my app.gradle is:

apply plugin: 'com.android.application'

android {

packagingOptions {

}

dexOptions {
    maxProcessCount 8
    javaMaxHeapSize "2g"
    preDexLibraries true
    keepRuntimeAnnotatedClasses false
}

compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion

flavorDimensions "target", "abi"

defaultConfig {
    applicationId "com.example"
    minSdkVersion rootProject.ext.minSdkVersion
    targetSdkVersion rootProject.ext.targetSdkVersion
    versionCode rootProject.ext.versionCode
    versionName rootProject.ext.versionName
    vectorDrawables.useSupportLibrary true
    multiDexEnabled true
}

signingConfigs {
    release {
        storeFile file("D:\\Keystore\\aaaaaaaa.jks")
        storePassword "aaaaaaa"
        keyAlias "avbbaaaaaa"
        keyPassword "ababababa"
    }
}

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

lintOptions {
    checkReleaseBuilds false
    // Or, if you prefer, you can continue to check for errors in release builds,
    // but continue the build even when errors are found:
    abortOnError false
}

dataBinding {
    enabled = true
}

productFlavors {
    vanilla {
        dimension "target"
        versionCode = 1
    }
    chrome {
        minSdkVersion 19
        dimension "target"
        versionCode = 2
    }
    ARMv7 {
        dimension "abi"
        versionCode = 4
    }
    x86 {
        dimension "abi"
        versionCode = 5
    }
    MIPS {
        dimension "abi"
        versionCode = 6
    }
    ARMv8 {
        dimension "abi"
        versionCode = 7
    }
    x86_64 {
        dimension "abi"
        versionCode = 8
    }
    MIPS64 {
        dimension "abi"
        versionCode = 9
    }
}
}

Finally I found out how to do this, I got this solution from https://developer.android.com/studio/projects/gradle-external-native-builds. Hope you also get from something here.

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {

      // For ndk-build, instead use the ndkBuild block.
      cmake {

        // Passes optional arguments to CMake.
        arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"

        // Sets a flag to enable format macro constants for the C compiler.
        cFlags "-D__STDC_FORMAT_MACROS"

        // Sets optional flags for the C++ compiler.
        cppFlags "-fexceptions", "-frtti"
      }
    }
  }

  buildTypes {...}

  productFlavors {
    ...
    demo {
      ...
      externalNativeBuild {
        cmake {
          ...
          // Specifies which native libraries or executables to build and package
          // for this product flavor. The following tells Gradle to build only the
          // "native-lib-demo" and "my-executible-demo" outputs from the linked
          // CMake project. If you don't configure this property, Gradle builds all
          // executables and shared object libraries that you define in your CMake
          // (or ndk-build) project. However, by default, Gradle packages only the
          // shared libraries in your APK.
          targets "native-lib-demo",
                  // You need to specify this executable and its sources in your CMakeLists.txt
                  // using the add_executable() command. However, building executables from your
                  // native sources is optional, and building native libraries to package into
                  // your APK satisfies most project requirements.
                  "my-executible-demo"
        }
      }
    }

    paid {
      ...
      externalNativeBuild {
        cmake {
          ...
          targets "native-lib-paid",
                  "my-executible-paid"
        }
      }
    }
  }

  // Use this block to link Gradle to your CMake or ndk-build script.
  externalNativeBuild {
    cmake {...}
    // or ndkBuild {...}
  }
}

Include prebuilt native libraries

If you want Gradle to package prebuilt native libraries with your APK, modify the default source set configuration to include the directory of your prebuilt .so files, as shown below. Keep in mind, you don't need to do this to include artifacts of CMake build scripts that you link to Gradle.

android {
    ...
    sourceSets {
        main {
            jniLibs.srcDirs 'imported-lib/src/', 'more-imported-libs/src/'
        }
    }
}

Specify ABIs

By default, Gradle builds your native library into separate .so files for the ABIs the NDK supports and packages them all into your APK. If you want Gradle to build and package only certain ABI configurations of your native libraries, you can specify them with the ndk.abiFilters flag in your module-level build.gradle file, as shown below:

android {
  ...
  defaultConfig {
    ...
    externalNativeBuild {
      cmake {...}
      // or ndkBuild {...}
    }

    // Similar to other properties in the defaultConfig block,
    // you can configure the ndk block for each product flavor
    // in your build configuration.
    ndk {
      // Specifies the ABI configurations of your native
      // libraries Gradle should build and package with your APK.
      abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
                   'arm64-v8a'
    }
  }
  buildTypes {...}
  externalNativeBuild {...}
}

Configure build variants, How can I package different *.so files for different Build flavors? Posted by: admin May 21, 2018 Leave a comment. Questions: I have some pre-build *.so files for  To build and run (or debug) any of the multiple flavors, Click the Build Variants tab, or select Build – Select Build Variant, and select the desired variant. Flavor specific code files While


By adding this script in app.gradle it works like a charm

ndk {
  // Specifies the ABI configurations of your native
  // libraries Gradle should build and package with your APK.
  abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a','arm64-v8a'
}

Building Multiple Versions of an Android App (Product Flavors), Creating product flavors is similar to creating build types: add Note: You still need to specify a package name using the package attribute in the main/ manifest file. product flavor a unique ID for packaging and distribution, Doing so gives you more control over which code and  Now how can you pick the right object based on the build type (Demo or Full)? You can't because to put your custom view in the xml layout android wants an absolute package. Yeah could be so cool have a dynamic namespace but then what's the purpose of the xml? and.. we have the flavors! So create different classes but with the same name MEditText.


Another solution would be to specify the jniLibs.srcDirs based on your flavor requirements, like this:

android {
...
   sourceSets {
      def flavor = getCurrentFlavor()
      if (flavor == ‘device’ || flavor == ‘production’) {
         jniLibs.srcDirs = ['libs']//or whatever path you have
      }
   ...

Where getCurrentFlavor() gets your build flavor name. You can find how to do it here:

How to get current flavor in gradle

How to build 17 apps with a single Android project and not go crazy, So to avoid this we can use Product Flavors. Product flavor defines a customized version of the application build by the project. A single project can Note: You can have different package name, app name, app icons, java class files and different attributes for each of the product flavors. Details of some are  Android Product Flavors are used to create different app versions. App versions can be free or paid. They can have different themes and texts. They can use different environments or APIs. Let’s assign two product flavors free and paid in our application.


Android Product Flavors - SG, This includes e.g. having different package names, version names, strings, Currently we have 17 flavors so this would take almost 3 hours to build on The lint tool checks your Android project source files for potential bugs  The Developer Preview for Android 11 is now available; test it out and share your feedback . This page builds on the Configure your build overview to show you how you can configure build variants to create different versions of your app from a single project, and how to properly manage your dependencies and signing configurations.


A Simple Guide to Android Product Flavors, Product flavors are nothing but preparing different dishes using the same Android by default uses two build types debug & release. So the order of picking any src file will be as follows for PaidDebug Build variant MinSdk version, TargetSdk version, versionName, versionCode, package name and  Create multiple flavors of an Android app using gradle script Posted on November 23, 2016 by Shekhar Sahu I’ve been asked sometimes on how to work with different hosts, different icons, or even different package names, depending on different versions of the same app.


FeatureExtension - Android Plugin 3.4.0-dev DSL Reference, Product Flavors so what are they? Simply put, a Build Type applies different build and packaging settings. An example of Open up your build.gradle file in the app module and add your flavors inside the android section. Will the executable of a small, extremely simple program, such as the one shown below, that is compiled on one flavor of Linux run on a different flavor? Or would it need to be recompiled? Does ma