新的實驗版插件是基於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。
原文。