原文:http://www.vogella.com/tutorials/AndroidBuild/article.htmlhtml
By default, Android projects are handled by the Gradle build system. If you create a new project in Android studio, the Gradle build scripts are automatically created. Android studio provides the Gradle runtime, hence no additional installation is required.java
默認,Android工程使用gradle來構建。若是使用Android studio建立一個新的工程,gradle 的構建腳本也會自動建立。由於Android sdudio 已經提供gradle的運行環境,所以您不須要額外的安裝。android
If you press the run button in Android Studio, it triggers the corresponding Gradle task and starts the application.ios
若是你按下Android studio中的run按鈕,將會觸發相對應的gradle任務,從而啓動應用。api
You can also run Gradle via the command line. To avoid unnecessary local installation, Gradle provides a wrapper script which allows you to run Gradle without any local installation.bash
你也能夠經過命令行運行gradle。爲了省去本地安裝gradle的麻煩,gradle提供了一個打包好的腳本(wrapper script ),這樣就能夠不用安裝gradle運行運行環境,直接運行gradle。閉包
You find the available versions of the Android Gradle plug-in under the following URL: jcenter.bintray.com/com/android…app
能夠在下面的鏈接中找到Android 的gradle插件:https://jcenter.bintray.com/com/android/tools/build/gradle/ide
The Java source files are converted to Java class files by the Java compiler. The Android SDK contains a tool called dxwhich converts Java class files into a .dex (Dalvik Executable) file. All class files of the application are placed in this .dexfile. During this conversion process redundant information in the class files are optimized in the .dex file. For example, if the same String
is found in different class files, the .dex file contains only one reference of this String
.工具
java編譯器將java源文件轉化成class文件。Android SDK中有一個工具叫dx
,他能夠將java文件轉化成 .dex (Dalvik 可執行的文件)文件。應用的全部文件都會被集中到這個.dex文件中。在這個處理過程當中,.dex 文件中的多餘信息會被精簡。例如,若是發現有多個文件中包含相同的字符串,最終.dex文件只保留一個.
These .dex files are therefore much smaller in size than the corresponding class files.
所以.dex 文件要比相對應的class文件要小。
The .dex file and other resources, e.g., the images and XML files, are packed into an .apk (Android Package) file. The program aapt (Android Asset Packaging Tool) performs this step.
.dex 文件和其餘資源,例如圖片和xml文件將會被打包進一個.apk(Android 包)文件。這個工做是由aapt工具完成
The resulting .apk file contains all necessary data to run the Android application and can be deployed to an Android device via the adb tool.
最終的.apk文件包含全部運行app所須要的全部資源,並且能夠經過adb工具部署到Android設備上。
As of Android 5.0 the Android RunTime (ART) is used as runtime for all Android applications. ART uses a combination of Ahead Of Time and _Just In Time _ compilation. During the installation of an application on an Android device, the application code is translated into machine code.
從Android 5.0 以後,ART 做爲了Android 的運行環境。ART 結合了AOT和JIT。當將應用安裝到設備時,會將應用代碼轉化成機器碼。
The dex2oat
tool takes the .dex file created by the Android tool chain and compiles that into an Executable and Linkable Format (ELF file). This file contains the dex code, compiled native code and meta-data. Keeping the .dex code allows that existing tools still work.
dex2oat
工具使用.dex文件將轉化成可運行、可鏈接的文件。這個文件包括dex代碼,機器碼,元數據。爲了兼容已經存在的工具,保留了dex代碼。
The Gradle build system is designed to support complex scenarios in creating Android applications:
gradle構建工具支持在構建Android應用的複雜場景。
You can start your Gradle build via the command line. Here is an overview of the important Android Gradle tasks:
你能夠經過命令行開始你的gradle構建。下面是一些重要的Android gradle 任務。
命令 | 描述 |
---|---|
./gradlew build |
build project, runs both the assemble and check task 構建工程,執行assemble 和 check任務 |
./gradlew clean build |
build project complete from scratch 從頭構建工程 |
./gradlew clean build |
build project complete from scratch 從頭構建工程 |
./gradlew test |
Run the tests 執行單元測試 |
./gradlew connectedAndroidTest |
Run the instrumentation tests 執行性能測試 |
To see all available tasks, use the gradlew wrapper
command.
gradlew wrapper
命令能夠查看全部任務。
gradle build
# alternatively speedup second grandle build by holding it in memory
# gradle build --daemon
複製代碼
This command creates in the build folder the output of the Gradle build. By default, the Gradle build creates two .apkfiles in the build/outputs/apk folder.
這個命令會將構建的結構輸出到build文件夾中。默認,gradle會在build/outputs/apk
文件夾中建立兩個.apk文件。
To build and start your unit tests on the JVM use the following command.
使用以下命令,執行單元測試
gradle test
複製代碼
To build and start your instrumented tests on your Android device use the following command.
使用以下命令,執行性能測試
gradle connectedCheck
複製代碼
The Gradle build system for Android supports resource shrinking at build time. This automatically removes resources that are unused from the packaged application. In addition to that, this also removes unnecessary resources from libraries you are depending on. This can hugely reduce the size of your application.
gradle會在編譯時對Android資源文件進行精簡。自動刪除應用不須要的資源。除此以外,也將刪除第三方包中無用的資。這樣會大大下降應用的大小。
To enable resource shrinking, update your build file similar to the following snippet.
更新您的構建文件以下,開啓資源精簡功能。
android {
...
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
複製代碼
A good practice is to define the version of your library dependencies outside the dependencies closure for better maintenance.
爲了維護的方便,最好將第三方包的版本信息保存在dependencies
閉包的外面,這是一個好的作法。
ext {
// App dependencies
junitVersion = '4.12'
mockitoVersion = '1.10.19'
powerMockito = '1.6.2'
hamcrestVersion = '1.3'
}
dependencies {
// Dependencies for local unit tests
testCompile "junit:junit:$junitVersion"
testCompile "org.mockito:mockito-all:$mockitoVersion"
testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
testCompile "org.powermock:powermock-module-junit4:$powerMockito"
testCompile "org.powermock:powermock-api-mockito:$ext.powerMockito"
}
複製代碼
If you put the ext closure into the root build file, you can access its properties for example with '$rootProject.ext.junitVersion'.
若是你將ext閉包放在根目錄的構建文件中,你能夠經過以下方式獲取:'$rootProject.ext.junitVersion'
Android uses by default two build types: debug and release. For these build types you can create different flavors in you Gradle build.
默認,Android使用兩種構建類型:debug和release。對於這些構建類型,能夠建立不一樣的風味
The Gradle build system is also able to manage different flavors of an application. A product flavor defines a customized version of the application. This allows that some parts of the codebase or the resources can be different for variations of the app.
gradle 可以管理應用的不一樣風味。一個產品風味定義一個自定義的應用。這就容許資源和代碼在不一樣的變體中有所不一樣。
For instance, you can define different build variants for certain device categories, like phone or tablet. Another use case might be a paid or a free version of your app. Or you want to use different resources or classes during a test run.
例如,你能夠定義不一樣的變體爲不一樣的設別類型,例如手機或者平板。另外,例如應用的付費和免費版本。或者你想在單元測試運行時,使用不一樣的資源和類。
You can use the productFlavors
closure of you app/build.gradle file to define different variants of your product.
可使用在app/build.gradle文件中的productFlavors
定義不一樣的變體。
productFlavors {
prod {
applicationId = "com.vogella.android.gradlebuildflavors.prod"
versionName = "1.0-paid"
}
mock {
applicationId = "com.vogella.android.gradlebuildflavors.mock"
versionName = "1.0-free"
}
}
複製代碼
The whole build.gradle file might look like the following:
整個個build.gradle 文件以下所示:
apply plugin: 'com.android.application'
android {
// as before....
productFlavors {
prod {
applicationId = "com.vogella.android.gradlebuildflavors.prod"
versionName = "1.0-paid"
}
mock {
applicationId = "com.vogella.android.gradlebuildflavors.mock"
versionName = "1.0-free"
}
}
}
// as before
複製代碼
After defining these flavors you can select them in the Build Variants view in Android Studio.
定義完風味以後,你就能夠在Android studio構建變體視圖中選擇他們了。
In order to define a different behavior for a certain flavor, you need to create suitable folders for the defined flavors under app/src/.
爲了爲某個風味定義不一樣的行爲,你須要爲定義的風味在app/src/文件夾下提供相應的文件夾,
Flavor specific resources override the main resources. For example, if you provide a different application icon in a flavor the Android build system picks up the flavor specific one.
風味特有的資源將覆蓋默認資源,例如,風味提供了應用icon,gradle 將選擇風味提供的。
The directories in the src/ folder are called source sets. Every product flavor can define its own source set.
src/ 文件被稱爲源集。每一個產品風味能夠定義本身的源集。
Code files are not replaced as resources, they are combined. For example, you cannot have acom.example.MainActivity
activity in your app/main/java/ folder and a different implementation in another flavor. If you try this, you receive an error message about duplicate class definitions.
源代碼文件是不能被替換的,而是結合。例如,你不能提供一個不一樣的com.example.MainActivity
不一樣的如今另外一個風味中。若是你試圖這樣,你將接受一個重複定義類的消息。
You can still provide different implementations by avoiding the creation of the class in your main source folder and instead create a class in each flavor.
經過不在默認的源集中提供實現,而是在每一個風味中提供。
In this exercise you create an Android application with two different project flavors, called prod and mock.
在這個練習中,你建立一個有兩個風味的Android應用,分爲叫prod和mock
The mock version defines different resources than the prod version. In this first sample the strings.xml file of the main folder/project is overridden. Which variant is build is defined via the Build Variants view.
mock版本和prod版本有不一樣的資源。第一個例子,主文件夾下的strings.xml文件將被覆蓋。經過構建變體視圖能夠定義變體的構建。
Create a new Project with the Empty Activity template and the top level package com.vogella.android.gradlebuildflavors
.
建立一個empty Activity 模板的Android新工程,設置頂層的報名爲:com.vogella.android.gradlebuildflavors
Define two additional product flavors in the app/build.gradle file called "prod" and "mock".
在app/build.gradle文件中定義兩個風味:prod和mock。
apply plugin: 'com.android.application'
android {
// as before....
productFlavors {
prod {
applicationId = "com.vogella.android.gradlebuildflavors.prod"
versionName = "1.0-paid"
}
mock {
applicationId = "com.vogella.android.gradlebuildflavors.mock"
versionName = "1.0-free"
}
}
}
// as before
複製代碼
Create the desired folder structure for prod and mock flavors.
爲prod和mock風味建立對應的文件結構。
Copy the strings.xml from the main folder to the appropriate folder of the flavor.
拷貝strings.xml文件從main文件夾到風味相對應的文件夾中
Change the hello_world
string of the strings.xml to Mock World! and Prod World! accordingly.
依次修改strings.xml文件中的hello wold字符串爲Mock World 和 Prod World
<resources>
<string name="app_name">Flavor</string>
<string name="hello_world">Mock World! </string>
</resources>
<resources>
<string name="app_name">Flavor</string>
<string name="hello_world">Prod World! </string>
</resources>
複製代碼
Select mockDebug
as Build Variant in the Build Variants view of Android Studio and run your app.
在Android studio的構建變體視圖中選擇mockDebug
,運行。
If you start you application you should see the string from the mock flavor. Select now you prod flavor and start it, you should see the other string.
加入你啓動你的應用,你應該看到來自mock風味的字符串。如今選擇prod風味,啓動應用,你應該看到另外一個字符串。
Use the ./gradlew build
command to build all your product flavors.
使用./gradlew build
命令構建全部的產品風味。
Create a class ShareIntentBuilder
which starts an activity via the 「share intent」 via a static method with the following code.
import android.content.Context;
import android.content.Intent;
public class ShareIntentBuilder {
public static void startSendActivity(Context context, String title, String body) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TITLE, title);
intent.putExtra(Intent.EXTRA_TEXT, body);
intent.setType("text/plain");
Intent chooserIntent = Intent.createChooser(intent, context.getResources().getText(R.string.share));
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(chooserIntent);
}
複製代碼
Allow the activity which triggers this intent to be replaced in your 「mock」 flavor. If in a flavor 「mock」 is selected, start a second activity in your application which displays the send data. If the flavor "prod" is selected send the shared intent.
進一步的解釋,在不一樣的風味中配置不一樣的class。
重命名apk
apply plugin: 'com.android.application'
android {
// more
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def file = output.outputFile
def filename = file.name.replace("app", "lars")
output.outputFile = new File(file.parent, filename)
}
}
// more
}
複製代碼
You can define a keystore in your build.gradle file. See tools.android.com/tech-docs/n…for details.
你能夠在build.gradle中定義keystore。
For example, you can redefine the keystore for the debug variant:
例如,你能夠爲debug變體重定義keystore。
android {
signingConfigs {
debug {
storeFile file("your.keystore")
}
}
}
複製代碼
省略