每次吃一点Androidのbuild.gradle详细配置说明

目录:
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、参考资料

Android小仙

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/stringsres3/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 开始 )【详细说明了哦~~~】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,077评论 25 707
  • 1.介绍 如果你正在查阅build.gradle文件的所有可选项,请点击这里进行查阅:DSL参考 1.1新构建系统...
    Chuckiefan阅读 12,131评论 8 72
  • 这一章主要针对项目中可以用到的一些实用功能来介绍Android Gradle,比如如何隐藏我们的证书文件,降低风险...
    acc8226阅读 7,606评论 3 25
  • 转至:http://blog.csdn.net/heqiangflytosky/article/details/5...
    kkgo阅读 2,873评论 0 1
  • 我们手牵手 雪中漫步 幻想就这样白了头 歌厅尽嚎 我们嚎的好汉歌 断断续续 因为我好开心 一直笑 而你在笑我 商铺...
    罗若阅读 187评论 1 3