每次吃一点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:.*:_*:!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/stringsres3/values/strings,如下图:

每次吃一点Androidのbuild.gradle详细配置说明_第1张图片

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~!!!

每次吃一点Androidのbuild.gradle详细配置说明_第2张图片

该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,索引不到该字符串:

每次吃一点Androidのbuild.gradle详细配置说明_第3张图片

前提:【没有配置: 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 开始 )【详细说明了哦~~~】

你可能感兴趣的:(每次吃一点Androidのbuild.gradle详细配置说明)