使用gradle构建和链接多个NDK库

Ale*_*int 5 gradle android-ndk

我有一个Android项目,它将一堆源代码链接到一个单一的JNI库中.我想将这个单独的库拆分成多个较小的库,它们之间有一些依赖关系.如何使用新的gradle构建系统实现这一目标?

dco*_*cow 1

您可以使用实验性 gradle 插件系列中的独立 Android 原生插件来实现这一点。新插件基于gradle 组件方法进行建模构建使用新系统有很多优点。

例如:

root
+ lib -> 'com.android.model.native'
+ lub -> 'com.android.model.native'
+ aar -> 'com.android.model.library'
+ app -> 'com.android.model.application'
Run Code Online (Sandbox Code Playgroud)

构建.gradle

configure([project(':lib'), project(':lub'), project(':aar'), project(':app')]) {
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha5'
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

库/build.gradle

apply plugin: "com.android.model.native"

model {
    android {
        compileSdkVersion 23
    ndk {
        moduleName "foo"
    }
    sources {
        main {
            jni {
                exportedHeaders {
                    srcDir "src/main/headers"
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

lub/构建.gradle

apply plugin: "com.android.model.native"

model {
    android {
        compileSdkVersion 23
    ndk {
        moduleName "bar"
    }
    sources {
        main {
            jni {
                exportedHeaders {
                    srcDir "include"
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

aar/build.gradle

apply plugin: "com.android.model.library"

model {
    android {
        buildToolsVersion '23.0.2'
        compileSdkVersion 23
    ndk {
        moduleName "aggregate-jni"
        stl "stlport_shared" // using cpp?
    }
    sources {
        main {
            jni {
                dependencies {
                    project ":lib"
                    project ":lub"
                }
            }
        }
    }
}    
Run Code Online (Sandbox Code Playgroud)

应用程序/build.gradle

apply plugin: 'com.android.model.application'

model {
    android {
        buildToolsVersion '23.0.2'
        compileSdkVersion 23 

        defaultConfig {
            applicationId "com.example.app"
            minSdkVersion.apiLevel 21
            targetSdkVersion.apiLevel 23
            versionCode 1
            versionName "1.0"
        }
    }
}

dependencies {
    compile project(':aar')
}
Run Code Online (Sandbox Code Playgroud)

如果链接是动态的(ndk 的默认链接),aar 将包含:

libfoo.so libbar.so libaggregate-jni.so libstlport.so
Run Code Online (Sandbox Code Playgroud)

和你的镜像java类。您可以简单地

System.load("aggregate-jni");
Run Code Online (Sandbox Code Playgroud)

您的 java 类和引用的库也会加载。如果链接是静态的,那么无论如何你最终都会得到一个链接libaggregate-jni.so。请注意,将一堆东西静态链接到 stl 是不好的,因为您最终会在二进制文件中得到 stl 的多个副本。这真的会把事情搞砸。

请注意,默认gcc工具链现已弃用。最好使用:

model {
    android {
        ndk {
            toolchain 'clang'
            stl 'c++_shared'
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

最后,您绝对不需要 aar,我只是为了完整性而将其包含在内。应用程序项目可以直接依赖于独立的本机 lib 项目,因为应用程序插件也完全支持 ndk。