新的实验版插件是基于Gradle的新组件模型机制的,它大大下降了配置时间。它还包含了NDK集成,以构建JNI应用程序。这份用户指南提供了关于如何使用它的详细信息,并特别指明了新的插件和原来的插件的不一样。java
警告:注意这个插件是插件的预览版,主要是为了获取关于性能和NDK的反馈。新组件模型的Gradle API尚未最终定稿,这意味每一个插件都只能与一个特定版本的Gradle一块儿工做。android
此外,DSL也可能改变。c++
请检查bintray repository来获取最新版本。git
每一个实验版插件须要一个特定版本的Gradle。这是所需的Gradle版本的列表。github
Plugin Version | Gradle Version |
---|---|
0.1.0 | 2.5 |
0.2.0 | 2.5 |
0.3.0-alpha3 | 2.6 |
0.4.0 | 2.8 |
0.6.0-alpha1 | 2.8 |
0.6.0-alpha5 | 2.10 |
0.7.0-alpha1 | 2.10 |
一个典型的Android Studio工程可能具备下面这样的目录结构。须要修改的文件被特别标示了红色:api
新的插件和传统的插件之间在DSL上具备很是大的变化。app
.
├── app/
│ ├── app.iml
│ ├── build.gradle
│ └── src/
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew*
├── gradlew.bat
├── local.properties
├── MyApplication.iml
└── settings.gradle性能
./gradle/wrapper/gradle-wrapper.propertiesgradle
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zipui
./build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// 你能够向顶层的构建文件中添加配置选项,这将用于全部的子项目/模块。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle-experimental:0.7.0-alpha4"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
// 注意:不要把你的应用程序的依赖放在这里;它们属于单独的模块的build.gradle文件
}
}
allprojects {
repositories {
jcenter()
}
}
./app/build.gradle
插件的DSL有一些很是重要的变化。咱们理解这些变化中的许多使人感到费解,甚至彷佛是不须要的,而咱们的目标是移除当前这些变化中的一些以最小化在将来由传统plugin到新版的迁移过程。
注意:相对于以前的版本,自版本0.6.0-alpha5起仍是有着很是重要的DSL提高。这里的示例代码将没法在以前的版本上工做。若是你要使用一个更老版本的插件,请参考下面位置的用户指南https://sites.google.com/a/android.com/tools/tech-docs/new-build-system/gradle-experimental/0-4-0。
DSL的变化:
当前DSL的以下一些限制有望消失:
apply plugin: "com.android.model.application"
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig {
applicationId "com.example.user.myapplication"
minSdkVersion.apiLevel 15
targetSdkVersion.apiLevel 22
versionCode 1
versionName "1.0"
buildConfigFields {
create() {
type "int"
name "VALUE"
value "1"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file("proguard-rules.pro"))
}
}
productFlavors {
create("flavor1") {
applicationId "com.app"
}
}
// Configures source set directory.
sources {
main {
java {
source {
srcDir "src"
}
}
}
}
}
}
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:22.2.0"
}
你可使用$()语法引用另外一个模型元素。要使用这一语法,"-Dorg.gradle.model.dsl=true"应该做为参数被添加到版本在2.10如下的Gradle的命令行上。这对于指定签名配置颇有用。注意:当前android.signingConfigs必需放在android {} 块的外面。
apply plugin: "com.android.model.application"
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
buildTypes {
release {
signingConfig = $("android.signingConfigs.myConfig")
}
}
}
android.signingConfigs {
create("myConfig") {
storeFile "/path/to/debug.keystore"
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
storeType "jks"
}
}
}
实验性插件包含了NDK集成,以建立native应用。要使用NDK集成,则:
一个简单的NDK应用的build.gradle看起来多是这样的:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
ndk {
moduleName = "native"
}
}
}
*注意moduleName是必须的。它决定了最终native library的名字。
默认状况下,它会到src/main/jni下去找C/C++文件。但能够配置android.sources来改变源码目录。
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
ndk {
moduleName = "native"
}
sources {
main {
jni {
source {
srcDir "src"
}
}
}
}
}
}
JNI源码集可能同时包含了C和C++文件。子目录中的全部文件都会被包含。文件扩展名是'.c'的会被看成是C文件,而C++文件则可能具备下面这些扩展名中的一种:'.C','.CPP','c++','.cc','.cp','.cpp','.cxx'。文件能够经过exclude方法来剔除,从而在include时被忽略:
model {
android.sources {
main {
jni {
source {
include "someFile.txt" // This is ignored.
exclude "**/excludeThisFile.c"
}
}
}
}
}
这种指定源码的根目录,而后用exclude方法剔除不须要编译的文件的方法,与Eclipse环境下在Android.mk文件中经过LOCAL_SRC_FILES变量指定要编译的文件的方式很是不同。
能够在android.ndk { }块内设置不一样的构建选项。好比,
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
ndk {
// All configurations that can be changed in android.ndk.
moduleName "native"
toolchain "clang"
toolchainVersion "3.5"
// Note that CFlags has a capital C, which is inconsistent with
// the naming convention of other properties. This is a
// technical limitation that will be resolved
CFlags.add("-DCUSTOM_DEFINE")
cppFlags.add("-DCUSTOM_DEFINE")
ldFlags.add("-L/custom/lib/path")
ldLibs.add("log")
stl "stlport_static"
}
buildTypes {
release {
ndk {
debuggable true
}
}
}
productFlavors {
create("arm") {
ndk {
// You can customize the NDK configurations for each
// productFlavors and buildTypes.
abiFilters.add("armeabi-v7a")
}
}
create("fat") {
// If ndk.abiFilters is not configured, the application
// compile and package all suppported ABI.
}
}
}
// You can modify the NDK configuration for each variant.
components.android {
binaries.afterEach { binary ->
binary.mergedNdkConfig.cppFlags.add(
"-DVARIANT=\"" + binary.name + "\"")
}
}
}
咱们日常见到的更多的场景是,将用到了NDK的Eclipse工程迁移到Android Studio,须要用build.gradle的配置来替换原来Android.mk和Application.mk这两个文件中的设置的情形。对于咱们的这种需求,上面的这个例子能够为咱们提供许多的帮助。
CFlags和cppFlags能够用来替换原来Android.mk中的LOCAL_CFLAGS和LOCAL_C_INCLUDES,以及Application.mk中的APP_CPPFLAGS。不过这里必定要注意,CFlags和cppFlags分别应用于C程序文件和C++程序文件的编译,好比项目中同时包含C程序文件和C++程序文件,对于某一个头文件,在C程序文件和C++程序文件中都有用到,则须要将该头文件的路径同时添加进CFlags和cppFlags。
ldLibs能够用来替换原来Android.mk中的LOCAL_LDLIBS。
stl能够替换原来Application.mk中的APP_STL。
abiFilters能够替换原来Application.mk中的APP_ABI。
能够在https://github.com/googlesamples/android-ndk找到其它的一些示例。
Plugin 0.4.0为NDK依赖添加了初步的支持及建立一个native library的能力。但请注意这只是咱们前进的方向上的一个预览版本,实现尚未完成。注意,尽管编译Gradle的native工程是可能的,但在Android Studio中的编辑和调试支持尚未实现。
在gradle-experimental:0.4.0中,建立了一个新的插件以容许在不建立一个Android应用程序和库的状况下只建立native库。DSL与application/library插件相似。下面的例子build.gradle能够由"src/main/jni"下的代码建立一个libhello.so。
apply plugin: "com.android.model.native"
model {
android {
compileSdkVersion 23
ndk {
moduleName "hello"
}
}
}
指定依赖的语法符合Gradle将来的依赖系统的风格。你能够设置对于一个Android工程或一个特定的文件的依赖。
好比,你在"lib"下有一个子工程使用了独立NDK插件:
lib/build.gradle:
apply plugin: "com.android.model.native"
model {
android {
compileSdkVersion 23
ndk {
moduleName "hello"
}
sources {
main {
jni {
exportedHeaders {
srcDir "src/main/headers"
}
}
}
}
}
}
任何有一个JNI依赖的工程将包含exportedHeaders中指定的目录。你能够在你的应用中为你的JNI代码添加对于lib工程的依赖:
app/build.gradle:
apply plugin: "com.android.model.application"
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
sources {
main {
jni {
dependencies {
project ":lib1"
}
}
}
}
}
}
你能够指定你的目标工程的build type和/或product flavor。不然插件将试着寻找与你的应用程序相同的build types和product flavor。若是你想要native库被静态地连接的话,你也能够指定linkage类型。好比:
model {
android.sources {
main {
jni {
dependencies {
project ":lib1" buildType "debug" productFlavor "flavor1" linkage "static"
}
}
}
}
}
要声明对一个文件的依赖,建立一个预编译库,并添加对于该库的依赖。好比,
model {
repositories {
libs(PrebuiltLibraries) {
prebuilt {
headers.srcDir "path/to/headers"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("lib/${targetPlatform.getName()}/prebuilt.so")
}
}
}
}
android.sources {
main {
jniLibs {
dependencies {
library "prebuilt"
}
}
}
}
}
警告:下个版本将有一个DSL的改动,使得Gradle能够内建支持预编译的库,相似于https://github.com/gradle/gradle/blob/master/subprojects/docs/src/samples/native-binaries/prebuilt/build.gradle。
你能够为'jniLibs'或'jni' source set添加native依赖。当给'jniLibs'添加了依赖时,native library将会被打包进application/library,但它不会被用于编译JNI代码。好比:
model {
android.sources {
main {
jniLibs {
dependencies {
library "prebuilt"
}
}
}
}
}
更多的应用场景应该是,咱们本身的JNI代码依赖于另外的一个so,不只仅须要在编译时让构建系统清楚这种依赖,还须要将这个so打包进application/library。对于这种状况,在'jni' source set添加native依赖是必不可少的,但也不能省略了'jniLibs'中对于该so的依赖的设置。不然就是,代码可以编译经过,但app在运行期间,load library的时候会crash,报出找不到某个so文件这样的错误。
能够看到'jni' source set添加native依赖能够替换Eclipse工程里Android.mk中的LOCAL_SHARED_LIBRARIES和LOCAL_STATIC_LIBRARIES。
这个插件仍然处于实验阶段。DSL将在插件的开发过程当中改变。这个部分描述了发生在不一样版本之间的改动,以帮助迁移。
0.6.0-alpha1 -> 0.6.0-alpha5
android {
buildTypes {
...
}
}
而不是
android.buildTypes {
...
}
model {
android.sources {
main {
jniLibs {
dependencies {
library file("lib/x86/prebuilt.so") abi "x86"
library file("lib/armeabi-v7a/prebuilt.so") abi "armeabi-v7a"
library file("lib/mips/prebuilt.so") abi "mips"
}
}
}
}
}
被替换为了:
model {
repositories {
prebuilt(PrebuiltLibraries) {
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("lib/${targetPlatform.getName()}/prebuilt.so")
}
}
}
android.sources {
main {
jniLibs {
dependencies {
library "prebuilt"
}
}
}
}
}
release {
jniDebuggable = true
}
becomes
release {
ndk.with {
debuggable = true
}
}
Done。
原文。