目录:
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:.*:_*:!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: 】***
现在:【一劳永逸,不用再注释来注释去了~~~】
*** 【AndroidManifest: 】***
*** 【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中:
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文件里面:
aapt_test_string_in_res2
res3/values/strings.xml文件里面:
aapt_test_string_in_res3
然后在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:.*:_*:!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,索引不到该字符串:
前提:【没有配置:
main.res.srcDirs = ['src/main/res', 'src/main/res3']
】
运行可以运行,内容也可以展示,但是点击原来那个button,却没有显示SnackBar的内容了。如有知道的伙伴,求指教!!!
参考资料: 编译时替换资源 - Android重叠包与资源合并一见
3. 打印配置信息
比如有这样一个meta-data:
我们可以在程序入口打印日志来统览所有配置信息,下面是打印其中一个配置:
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 开始 )【详细说明了哦~~~】