編輯:關於Android編程
新項目中,使用了Google I/O 2013發布的新工具,使用Gradle構建android項目,並且在新版的Intellig IDEA以及google的Android Studio對其支持。本文就介紹一下怎麼使用gradle構建android項目,進行多個版本編譯。
Gradle是以Groovy為基礎,面向java應用,基於DSL語法的自動化構建工具。是google引入,替換ant和maven的新工具,其依賴兼容maven和ivy。
使用gradle的目的:
更容易重用資源和代碼;
可以更容易創建不同的版本的程序,多個類型的apk包;
更容易配置,擴展;
更好的IDE集成;
Gradle1.10或者更高版本,grale插件0.9或者更高版本.
android SDK需要有Build Tools 19.0.0以及更高版本
使用ide創建的gradle構建的項目,會自動創建一個build.gradle,如下:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.0'
}
}
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.0"
}
可以看到,構建文件主要有三個區域:
buildscript{...}
Configures the build script classpath for this project. 設置腳本的運行環境
apply plugin: 'android'
設置使用android插件構建項目
android{...}
設置編譯android項目的參數
通常會有以下任務:
assemble The task to assemble the output(s) of the project(輸出一個項目文件,android就是打包apk)
check The task to run all the checks.(運行檢查,檢查程序的錯誤,語法,等等)
build This task does both assemble and check (執行assemble和check)
clean This task cleans the output of the project(清理項目輸出文件)
上面的任務assemble,check,build實際上什麼都不做,他們其實都是其他任務的集合。
執行一個任務的方式為gradle 任務名
, 如gradle
assemble
在android項目中還有connectedCheck(檢查連接的設備或模擬器),deviceCheck(檢查設備使用的api版本)
通常我們的項目會有至少生成兩個版本,debug和release,我們可以用兩個任務assembleDebug和assembleRelease去分別生成兩個版本,也可以使用assemble一下子生成兩個版本。
gradle支持任務名縮寫,在我們執行gradle assembleRelease的時候,可以用gradle aR代替。
我們可以在build.gradle文件中配置我們的程序版本等信息,從而可以生成多個版本的程序。
支持的配置有:
minSdkVersion 最小支持sdk版本
targetSdkVersion 編譯時的目標sdk版本
versionCode 程序版本號
versionName 程序版本名稱
packageName 程序包名
Package Name for the test application 測試用的程序包名
Instrumentation test runner 測試用的instrumentation實例
例如:
android {
compileSdkVersion 19
buildToolsVersion "19.0.0"
defaultConfig {
versionCode 12
versionName "2.0"
minSdkVersion 16
targetSdkVersion 16
}
}
默認情況下項目目錄是這樣的
有兩個組件source sets,一個main,一個test,對應下面兩個文件夾。
src/main/
src/androidTest/
然後對於每個組件目錄都有兩個目錄,分別存儲java代碼和資源文件
java/
resources/
對於android項目中呢,對應的目錄和文件是
AndroidManifest.xml //該文件src/androidTest/目錄下不需要,程序執行時會自動構建
res/
assets/
aidl/
rs/
jni/
如果需要上面這些文件,但是不是在上面所說的目錄,則需要設置。
sourceSets {
main {
java {
srcDir 'src/java'
}
resources {
srcDir 'src/resources'
}
}
}
可以給main或者test設置根目錄,如
sourceSets {
androidTest.setRoot('tests')
}
可以指定每種文件的存儲路徑
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
特別是我們的ndk生成的.so文件,通常我們不是放到jni目錄中的,我們需要設置一下
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
可以給不同類型進行不同的配置,先看示例:
android {
signingConfigs {
debug {
storeFile file("debug.keystore")
}
myConfig {
storeFile file("other.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
buildTypes {
foo {
debuggable true
jniDebugBuild true
signingConfig signingConfigs.myConfig
}
}
}
上面的配置文件配置兩個類型,一個時debug類型,一個時自己的自定義類型。兩個分別使用了不同的簽名,同時對於生成密鑰,要填寫設置的密碼。
直接看代碼:
android {
buildTypes {
release {
runProguard true
proguardFile getDefaultProguardFile('proguard-android.txt')
}
}
}
以上是使用默認的proguard文件去進行混淆,也可以使用自己編寫的規則進行混淆,proguardFile 'some-other-rules.txt'
程序中會依賴別的包,或者程序,需要引入別的類庫。前面也說到了,支持maven。
對於本地的類庫,可以這樣引入:
dependencies {
compile files('libs/foo.jar') //單個文件
compile fileTree(dir: 'libs', include: ['*.jar']) //多個文件
}
android {
...
}
對於maven倉庫文件:
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.guava:guava:11.0.2'
}
android {
...
}
看代碼:
android {
...
defaultConfig {
minSdkVersion 8
versionCode 10
}
productFlavors {
flavor1 {
packageName "com.example.flavor1"
versionCode 20
}
flavor2 {
packageName "com.example.flavor2"
minSdkVersion 14
}
}
}
通過以上設置,我們可以輸出不同的保命不同的版本號,以及最小sdk的程序包。當然我們可以根據自己的需求去做其他的不同
我的完整配置文件
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 8
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
lintOptions {
abortOnError false
}
//簽名
signingConfigs {
//你自己的keystore信息
release {
storeFile file("×.keystore")
storePassword "×××"
keyAlias "××××"
keyPassword "×××"
}
}
buildTypes {
debug {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
//渠道Flavors,我這裡寫了一些常用的,你們自己改
productFlavors {
//GooglePlay{}
//Store360{}
//QQ{}
//Taobao{}
//WanDouJia{}
//AnZhuo{}
//AnZhi{}
//BaiDu{}
//Store163{}
//GFeng{}
//AppChina{}
//EoeMarket{}
//Store91{}
//NDuo{}
xiaomi{}
umeng{}
}
}
//替換AndroidManifest.xml的UMENG_CHANNEL_VALUE字符串為渠道名稱
android.applicationVariants.all{ variant ->
variant.processManifest.doLast{
//之前這裡用的copy{},我換成了文件操作,這樣可以在v1.11版本正常運行,並保持文件夾整潔
//${buildDir}是指./build文件夾
//${variant.dirName}是flavor/buildtype,例如GooglePlay/release,運行時會自動生成
//下面的路徑是類似這樣:./build/manifests/GooglePlay/release/AndroidManifest.xml
def manifestFile = "${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml"
//將字符串UMENG_CHANNEL_VALUE替換成flavor的名字
def updatedContent = new File(manifestFile).getText('UTF-8').replaceAll("UMENG_CHANNEL_VALUE", "${variant.productFlavors[0].name}")
new File(manifestFile).write(updatedContent, 'UTF-8')
//將此次flavor的AndroidManifest.xml文件指定為我們修改過的這個文件
variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml")
}
}
以上的功能就是替換我的Manifest中的umeng渠道標示,同時去生成不同的apk包。
程序在buid的時候,會執行lint檢查,有任何的錯誤或者警告提示,都會終止構建,我們可以將其關掉。
lintOptions {
abortOnError false
}
本人使用gradle確實方便很多,雖然電腦配置低,build的時候比較慢。
內容呢,主要時參考谷歌官方的文檔。
關於怎麼安裝,沒有講到,可以參考這篇文章:http://stormzhang.github.io/android/2014/02/28/android-gradle/
附上我參考的文檔,沒看懂的可以去看看。http://tools.android.com/tech-docs/new-build-system/user-guide
在Android開發過程中,ListView的Adapter是我們最常見的類型之一,我們需要使用Adapter加載Item View的布局,並且進行數據綁定、緩存復用等操
周三谷歌推出下一個流行的移動操作系統Android L。但是只提供了簡單地預覽版本,稍後將提供一個開發者預覽版,完整版計劃在今年秋天發布。 下面我們一起來看看如何
Contact providerContact provider是一個強大而又靈活的 Android 組件,用於管理設備上有關聯系人數據的中央存儲庫。 Contact p
什麼是ListView分頁加載數據功能呢?在現在的大數據時代,我們不可能把某些數據全部展示到界面,好比我們經常會看的QQ空間一樣,當你看動態的時候,系統不可能會把所有好友