目錄:
1、build.gradle(app)實例說明
2、對照說明
--2.1. apply plugin
--2.2. manifestPlaceholders
--2.3. dataBinding
--2.4. sourceSets
--2.5. productFlavors
--2.6. applicationVariants.all
--2.7. aapt重疊包配置
3、打印配置信息
4、此外【自定義config.gradle】
5、參考資料
1. build.gradle(app)實例說明
apply plugin: 'com.android.application' // 使用android app插件
android {
compileSdkVersion 22 // 編譯的SDK版本
buildToolsVersion "25.0.0" // 編譯工具的版本
// 默認的基本配置
defaultConfig {
applicationId "com.conquer.elspet.conqueryo" // 應用的包名
minSdkVersion 15 // 支持的SDK最低版本
targetSdkVersion 22 // 目標SDK版本
versionCode 1 // 版本號
versionName "1.0" // 版本名稱
// manifestPlaceholders可以替換AndroidManifest中的標簽
// 也可以放在buildTypes中對調試和發布做不同的配置
manifestPlaceholders = [CHANNEL_ID: "_test"]
}
// 調試/打包的簽名配置
// 重要:::signingConfigs一定要放在調用之前,也就是要在buildTypes之前定義好
signingConfigs {
debug {
// 可以跟release配置一樣,這樣調試微信登錄這樣的就可以直接調試測試了
}
release {
storePassword 'conqueryo'
storeFile file('../keystore/conquer.keystore')
keyPassword 'conqueryo'
keyAlias 'conquer'
}
}
// 設置重疊包機制,實現資源合并,謹慎使用,如果有圖片有問題會報錯
// 若出錯,可設置:
// aaptOptions.cruncherEnabled = false;
// aaptOptions.useNewCruncher = false;
aaptOptions {
additionalParameters '-S',
'/ConquerYoFolder/ConquerYo/app/src/main/res2',
'-S',
'/ConquerYoFolder/ConquerYo/app/src/main/res3',
'--auto-add-overlay'
noCompress 'foo', 'bar'
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
// 發布和調試時的配置
buildTypes {
debug {
debuggable true
minifyEnabled false
signingConfig signingConfigs.release
// signingConfig signingConfigs.debug
}
release {
debuggable false
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
// 關閉DataBinding功能
dataBinding {
enabled = false
}
sourceSets {
main {
jniLibs.srcDir 'libs'
}
}
productFlavors {
_test {}
qh360 {}
baidu {}
yingyongbao {}
wandj {}
xiaomi {}
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [CHANNEL_ID: name]
}
//給生成的apk文件重命名,
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':emojicon')
compile project(':jRecyclerView')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:22.+'
compile 'com.android.support:design:22+'
compile 'com.android.support:cardview-v7:22.+'
compile 'com.android.support:support-v4:22.+'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'jp.wasabeef:glide-transformations:2.0.0'
compile 'com.yqritc:recyclerview-flexibledivider:1.2.9'
compile 'com.nineoldandroids:library:2.4.0'
compile 'com.qiniu:qiniu-android-sdk:7.1.0'
compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.+'
compile 'org.greenrobot:eventbus:3.0.0'
}
2. 配置說明
2.1. apply plugin
聲明該module中使用的插件。那么有哪些插件可以使用???
比較常見的插件:
-
com.android.application
:安卓應用插件 -
com.android.library
:安卓庫插件,注意不能與安卓應用插件同時使用
其他插件:
-
me.tatarka.retrolambda
:使用Lambda表達式的插件 -
android-apt
:處理注釋的插件工具
我們在使用ButterKnife做依賴注入的時候,就需要使用到處理注釋的插件工具:com.neenbedankt.android-apt
其他還沒發現或使用到,后續補充------
2.2. manifestPlaceholders
manifestPlaceholders
可以用來替換androidmanifest文件中的標簽,可作為快速渠道打包替換渠道名的一種方式,也可以自定義標簽用來替換需要的文本,多作為不同環境不同key的修改。
我們在使用第三方SDK的時候,常常有區分debug_key和release_key,測試的時候用debug_key,發布的時候用release_key,抓狂的是每次測試跟發布狀態切換的時候常常忘記切換這兩個配置,導致出錯。有了manifestPlaceholders
,就不用再為這等小問題煩惱了。
以前:
*** 【AndroidManifest: 】***
<!-- 融云 -->
<!-- 開發環境 -->
<meta-data
android:name="RONG_CLOUD_APP_KEY"
android:value="vnrofffffffuzo" />
<!-- 測試環境 然后轉測試的時候將上段注釋,下段解掉注釋-->
<!--<meta-data
android:name="RONG_CLOUD_APP_KEY"
android:value="k51hfffffff1bh5b" /> -->
現在:【一勞永逸,不用再注釋來注釋去了~~~】
*** 【AndroidManifest: 】***
<!-- 融云 -->
<meta-data
android:name="RONG_CLOUD_APP_KEY"
android:value="${rong_cloud_app_key}" />
*** 【build.gradle(app): 】***
buildTypes {
debug {
manifestPlaceholders = [rong_cloud_app_key : "k51hfffffff1bh5b"]
}
release {
manifestPlaceholders = [rong_cloud_app_key : "vnrofffffffuzo"]
}
}
2.3. dataBinding
DataBinding
是谷歌于15年推出的數據綁定框架。取代findViewById(),解耦。
使用說明:
2.3.1. build.gradle中的配置
android {
....
dataBinding {
enabled = true
}
}
2.3.2. 數據實體類User:
package com.conquer.elspet.conqueryo.mvp.model.entity;
/**
* User Entity
*/
public class User {
private String name;
private String sex;
public User(String name, String sex) {
this.name = name; // 名字
this.sex= sex; // 性別
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex= sex;
}
public String getName() {
return this.name;
}
public String getSex() {
return this.sex;
}
}
2.3.3. layout中:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.conquer.elspet.conqueryo.mvp.model.entity.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.sex}" />
</LinearLayout>
</layout>
2.3.4. 在Activity中
public class UserInfoActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_user_info);
User user = new User("LisaTheCat", "female");
binding.setUser(user);
}
}
參考資料:Android數據綁定框架DataBinding,堪稱解決界面邏輯的黑科技
2.4. sourceSets
資源目錄指向配置,可以指定哪些源文件(或文件夾下的源文件)要被編譯,哪些源文件要被排除。手動配置項目的目錄結構
android {
....
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
}
2.5. productFlavors
利用productFlavors可以定義不同產品(apk)的特性,不同的產品可以定義不同的包名、使用不同的資源庫、使用不同的代碼、不同的渠道號、不同的資源文件等等。
productFlavors{
// 產品A(名字為:productA)
productA{
// 配置產品A獨立的包名,獨立的版本號,渠道名
applicationId "com.crazyman.product.a"
versionName "version-a-1.0"
manifestPlaceholders.put("UMENG_CHANNEL_VALUE", "productA")
}
// 產品B(名字為:productB)
productB{
// 配置產品B獨立的包名,獨立的版本號,渠道名
applicationId "com.crazyman.product.b"
versionName "version-b-1.0"
manifestPlaceholders.put("UMENG_CHANNEL_VALUE", "productB")
}
}
2.6. applicationVariants.all
applicationVariants.all
:應用插件的所有變量
libraryVariants
:庫插件的所有變量
testVariants
:適用庫插件和應用插件的所有變量
可以做一些配置。比如下面一段配置就是設置打包apk的apk名稱:
//給生成的apk文件重命名,
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
假設在不配置的情況下打包出來的apk文件為:app-debug.apk
,那么加上該配置后改為:app-debug-1.0.apk
。
假設我們還增加了不同產品的配置:
productFlavors {
baidu {}
xiaomi{}
}
那么到時候我們打包出來的就是:
app-baidu-debug-1.0.apk
app-xiaomi-debug-1.0.apk
2.7. aapt重疊包配置
aaptOptions可以對項目中相同資源進行合并。
在工程目錄的main文件夾下新建兩個文件res2/values/strings
和res3/values/strings
,如下圖:
res2/values/strings.xml文件里面:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="aapt_test_string">aapt_test_string_in_res2</string>
</resources>
res3/values/strings.xml文件里面:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="aapt_test_string">aapt_test_string_in_res3</string>
</resources>
然后在Activity中使用,例如點擊Button,顯示SnackBar:
Snackbar.make(button, getResources().getString(R.string.aapt_test_string), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
然后報錯了,額呵呵O(∩_∩)O~!!!
該aaptOptions出場了,在build.gradle(app)中添加:
aaptOptions {
additionalParameters '-S',
'/ConquerYoFolder/ConquerYo/app/src/main/res2',
'-S',
'/ConquerYoFolder/ConquerYo/app/src/main/res3',
'--auto-add-overlay'
noCompress 'foo', 'bar' // foo和bar相當于現實當中的無名氏,常被作為偽變量使用
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
上述代碼配置意在將res3合并到res2中,res3會被覆蓋掉,最后點擊button,SnackBar顯示的是:aapt_test_string_in_res2
,假設將這配置中的res2跟res3的位置替換一下,那么顯示的將變成:aapt_test_string_in_res3
。
再進一步:在build.gradle(app)中繼續添加:
android.sourceSets {
main.res.srcDirs = ['src/main/res', 'src/main/res3']
}
aaptOptions的配置依舊同上,這個時候再點擊button時,顯示的就不是aapt_test_string_in_res2
了,因為res3已經優先跟res合并了。
然而,我遇到了另一個不明之處:
我在布局文件中引用了aapt_test_string,索引不到該字符串:
<a>前提:</a>【沒有配置:
main.res.srcDirs = ['src/main/res', 'src/main/res3']
】運行可以運行,內容也可以展示,但是點擊原來那個button,卻沒有顯示SnackBar的內容了。如有知道的伙伴,求指教!!!
參考資料:編譯時替換資源 - Android重疊包與資源合并一見
3. 打印配置信息
比如有這樣一個meta-data:
<meta-data
android:name="RONG_CLOUD_APP_KEY"
android:value="${rong_cloud_app_key}" />
我們可以在程序入口打印日志來統覽所有配置信息,下面是打印其中一個配置:
String rongyun_appkey;
try {
ApplicationInfo appInfo = getPackageManager()
.getApplicationInfo(getPackageName(),
PackageManager.GET_META_DATA);
rongyun_appkey= appInfo.metaData.getString("RONG_CLOUD_APP_KEY");
Logger.d("rongyun_appkey=" + rongyun_appkey);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
4. 此外【自定義config.gradle】
如果項目中涉及的module比較多,每個Module都需要做build.gradle的配置,牽一發而動全身,假設有個第三方庫的版本要修改,可能要到每個build.gradle文件中做修改。這個時候我們可以通過在根目錄下自定義一個配置文件,假設命名為:config.gradle
,然后在里面做一些配置,讓其他每個模塊的build.gradle都來引用這里面的配置就好了。
config.gradle
ext {
android = [compileSdkVersion : 25,
buildToolsVersion : "25.0.2",
minSdkVersion : 15,
targetSdkVersion : 25,
versionCode : 1,
versionName : "1.0.1",
androidSupportSdkVersion: "25.1.1",
retrofitSdkVersion : "2.1.0",
]
dependencies = [
"support-v4" : "com.android.support:support-v4:${android["androidSupportSdkVersion"]}",
"cardview-v7" : "com.android.support:cardview-v7:${android["androidSupportSdkVersion"]}",
"retrofit" : "com.squareup.retrofit2:retrofit:${android["retrofitSdkVersion"]}",
"gson" : "com.google.code.gson:gson:2.7",
]
}
如上,本配置文件中引用,dependencies引用android:${android["引用的標簽名"]}
build.gradle(app)
android {
// 編譯的SDK版本:
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
}
如上,子module的build.gradle中引用,rootProject.ext.android["引用的標簽名"]
5. 參考資料
Android Gradle manifestPlaceholders 的妙用
Gradle for Android 第一篇( 從 Gradle 和 AS 開始 )【詳細說明了哦~~~】