Assume I have a bunch of code for Android I wish to reuse across projects. It includes Java code along with some native C++ code. I use Gradle + CMake to build my project.

What is the best way to organize it? What I want is a self-contained 'module' within a separate directory containing cpp, java code, some config files (Gradle scripts and CMakeLists.txt, etc).

When I start new project from a scratch I just want to throw in this submodule and include java and native parts with as little messing around as possible. What are my options?

EDIT: I have troubles making Gradle build native code for submodules.

Here is my main app gradle:

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.palmkingdoms.pk2_remastered"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

And here is a sub-mobule gradle:

apply plugin: 'java-library'
apply plugin: 'kotlin'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

sourceCompatibility = "7"
targetCompatibility = "7"
buildscript {
    ext.kotlin_version = '1.3.31'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

repositories {
    mavenCentral()
}
compileKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
compileTestKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

I just don't know where to put that externalNativeBuild directive.

1 Answers

0
Alex Cohn On

I believe that you have just described the perfect setup. I guess that only one detail is missing: this self-contained module will be an Android Library module. The official reference explains how such module can be created in Android Studio, or how you can convert an existing Application module into a Library.

When they mature and you want to distribute such library to other developers, you can export a compiled AAR that can be used without access to your C++ sources, and even does not require NDK installation.