Android Gradle中的productFlavors

目录

前言

一 productFlavors

1.productFlavors基本使用

 2. productFlavors的variants输出

二 productFlavors应用场景

三 总结


前言

        前段时间在研究Android自定义插件的一系列内容(具体见 Android 自定义Gradle插件的多层属性扩展(五))的时候
,接触到android{}中的productFlavors该扩展属性,觉得很有意思,简单的总结下。

一 productFlavors

        productFlavors是android{}中的一个扩展属性,主要用来让同一套代码可以打包成不同的apk包,又可以成为变体(Variants)。其实该productFlavors属性是与buildTypes配合使用的,后面会列举。先从一个实例中来看下这个扩展属性怎么用。

1.productFlavors基本使用

        通常使用productFlavors{}可以使用一套代码来产生多个apk包,例如多渠道打包。

  • (1)在AndroidManifest中添加一个<meta-data>

        添加该<meta-data>用来标记多渠道,代码如下:

        <!--设置多渠道-->
        <meta-data
            android:name="channel"
            android:value="${CHANNEL}" />
  •  (2)在build.gradle中添加该productFlavors{}

        在app下的build.gradle中通过productFlavors为AndroidManifest中的meta-data赋值,代码如下:

//特色产品:同一套代码生产出不同特色的产品
    flavorDimensions "channel"
    productFlavors {
        huawei {
            manifestPlaceholders = [CHANNEL: "huawei"]
            dimension = "channel"
        }

        oppo {
            manifestPlaceholders = [CHANNEL: "oppo"]
            dimension = "channel"
        }

        xiaomi {
            manifestPlaceholders = [CHANNEL: "xiaomi"]
            dimension = "channel"
        }

    }
}

        对于在productFlavors{}下面的每个闭包都是一个flavor,注意从Android Studio 3.0.0之后,在使用productFlavors{}的时候,必须为每个flavor设置一个dimension。这个dimension可以理解为对flavor进行分组,不同的dimension中的flavor会组合成一个变体variants。如果不设置dimension,则会在build输出窗口抛出下面异常:

All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html

         进入到错误的提示链接中发现:

        

         第一句话明确说明需要给每一个flavor设置一个dimension。

        当然官网也给到解决方案:使用flavorDimensions定义dimension,即apk的维度;然后给到每个闭包flavor设置对应的dimension即可,如同所示:

        

          写在第一个的维度的优先级最高,最后会以所有维度的笛卡尔积来产生variant的数量,最后配合为每个variant添加buildTypes{}中的定义的类型,生成最后的variant。  对项目进行编译之后,可以看到在Build Variants窗口中就可以看到有6个variant。

        

        默认的在通过Android Studio的Run运行,只会产生一个apk,但是通过Generate Signed Bundle or APK,即如下窗口   

                    

        可以任意选择要生成签名的variant来进行打包签名。

        最后在代码中可以打印出该<meta-data>中的值,代码如下:

 private String getChannelFromAndroidManifest() {
        String metaChannel = "";
        try {
            ApplicationInfo info = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
            if (info == null || info.metaData == null) {
                return metaChannel;
            }
            metaChannel = info.metaData.getString("channel");
        } catch (PackageManager.NameNotFoundException e) {
        }
        return metaChannel;
    }

        发现与在build.gradle中设置的值保持一致。具体的代码已经上传到至https://github.com/wenjing-bonnie/AndroidPlugin.git的app目录的相关内容。因为逐渐在这基础上进行迭代,可回退到Gradle_5.0.1该tag下可以查看相关内容。

 2. productFlavors的variants输出

        其实在Android Gradle提供了对应的api来将输出所有的variant变体的信息,在项目配置完成之后,可以通过this.android.applicationVariants.all将所有的variants的信息输出,例如name:


this.afterEvaluate {
    this.android.applicationVariants.all { variant ->
        println(prefix + "name = " + variant.name)
    }
}

        通过Android Studio编译项目,发现Build输出窗口会输出每个variant的name,如下:

@@@@@@@@@@@@@@ app @@@@@@@@@@@@@   name = huaweiDebug
@@@@@@@@@@@@@@ app @@@@@@@@@@@@@   name = oppoDebug
@@@@@@@@@@@@@@ app @@@@@@@@@@@@@   name = xiaomiDebug
@@@@@@@@@@@@@@ app @@@@@@@@@@@@@   name = huaweiRelease
@@@@@@@@@@@@@@ app @@@@@@@@@@@@@   name = oppoRelease
@@@@@@@@@@@@@@ app @@@@@@@@@@@@@   name = xiaomiRelease

二 productFlavors应用场景

        前面主要总结了productFlavors的一个基本使用,那么在Android开发中productFlavors可以用来做什么呢?

  • 1.同一套代码维护了面向不同用户的apk

        像一个APK可以打包成一个debug版本和一个release版本,需要在一个手机上同时安装这两个apk。我们知道对于这两个apk如果包名一致的话,肯定会相互覆盖,那么就可以采用productFlavors{}来为每个variant设置不同的applicationId,那么打包成的两个apk会共用同一套代码,但是包名不一致,所以可以同时安装在同一个手机上。相比较于1.productFlavors基本使用仅仅是将在不同的flavor闭包为不同的flavor设置"applicationId = xxxx"即可。

  • 2.多渠道打包

        像在1.productFlavors基本使用的例子就是设置的多渠道打包的方式,可以通过productFlavors{}对<meta-data> 设置不同的渠道值。

  • 3.针对不同的手机设置不同的应用icon、文字或其他信息

       像Android各大手机厂商,有自己的手机系统的应用icon的样式,那么就可以通过 productFlavors{}来设置不同的icon,其步骤大体如下:

        (1)按照在1.productFlavors基本使用设置好不同的渠道标识;

        (2)在项目的src的同级目录右击src目录,选择New Resource Directory ,在弹出的对话框中选择src/huawei/res依次新建放置icon的不同的资源包,如图所示:

              

        创建之后的项目目录如下所示:

        ​​

         这样每个flavor会先读取本flavor对应的目录下读取对应的代码或者资源文件,如果没有的话,才会去main目录下进行查找。这样在Build Variants的窗口中选择huaweiDebug,运行到手机中,发现对应的icon已经更换

          具体的代码已经上传到至GitHub - wenjing-bonnie/AndroidPlugin: 用来学习Android Gradle Plugin的app目录的相关内容。因为逐渐在这基础上进行迭代,可回退到Gradle_5.0.1该tag下可以查看相关内容。

        对于其他内容如代码、文案等的修改同样如此。

  • 4.简单的不同flavor值的设置

        像在 1.productFlavors基本使用使用的通过<meta-data>设置一个简单的字符串,在代码中取需要比较多的代码,才可以获取到该值,其实如果仅仅是简单的设置一些值的区别,可以直接使用buildConfigField来设置即可,代码如下:

productFlavors {

        huawei {
            manifestPlaceholders = [CHANNEL: "huawei"]
            dimension = "channel"
            buildConfigField("String","CHANNEL","\"huawei\"")
        }

        oppo {
            manifestPlaceholders = [CHANNEL: "oppo"]
            dimension = "channel"
            buildConfigField("String","CHANNEL","\"oppo\"")
        }

        xiaomi {
            manifestPlaceholders = [CHANNEL: "xiaomi"]
            dimension = "channel"
            buildConfigField("String","CHANNEL","\"xiaomi\"")
        }
    }

        而在代码中只需要通过BuildConfig.CHANNEL就可以取得设置的渠道值。

  • 5.对variant进行不同的处理

        在前面的 2. productFlavors的variants输出可以通过this.android.applicationVariants.all将所有的variants输出,那么就可以针对不同的variants来进行单独处理。例如可以得到每个variant的Task,针对所需的Task进行Hook,如图所示:

        

        代码如下:

this.afterEvaluate {
    //当前variant的类型为application类型
    this.android.applicationVariants.all { ApplicationVariant variant ->
        println(prefix + "name = " + variant.name)
        //得到每个variant中的task,然后进行对Task进行hook
        variant.getAssembleProvider().get().doFirst {
            println(prefix + " assemble task do first ")
        }
    }
}

三 总结

productFlavors{}主要用来针对一套代码打包成多个有差异的apk。

  • 1.productFlavors{}下的每个闭包就是一个flavor,也可称为变体variant;
  • 2.定义一个variant,需要设定dimension。需要通过flavorDimensions来定义dimension;
  • 3.每个dimension称为一个分组,多个不同的dimension通过笛卡尔积的形式得到一个variant,最后结合buildTypes{}里面配置的项,形成最终的variant
  • 4.如果只是简单的逻辑的差异,可以通过BuildConfigField进行设置差异,当然可以通过<meta-data>的形式来设置差异;
  • 5.对于每个variant在main的同级目录下都有一个对应的资源目录和代码目录,在打包成apk的时候,首先会读取对应的variant的相应目录,没有的话再去读取main下的目录内容;
  • 6.可通过this.android.applicationVariants.all在项目配置完成之后,得到所有的variants,每个variant是一个ApplicationVariant,可以得到该variant中的task、name等信息

           加油,越来越好玩了。

### 回答1: Gradle是一种基于Apache Ant和Apache Maven概念的自动化构建工具,用于Java项目的自动化构建、依赖管理和测试等。在Android StudioGradle被用来构建和管理Android项目。 Gradle的配置包括: 1. 项目级别的Gradle配置:位于项目根目录下的build.gradle文件,用于配置整个项目的构建和依赖管理。 2. 模块级别的Gradle配置:位于每个模块的build.gradle文件,用于配置该模块的构建和依赖管理。 在Gradle配置,常见的配置项包括: 1. repositories:用于指定依赖库的仓库地址,可以是本地文件系统、远程Maven仓库或者其他自定义仓库。 2. dependencies:用于指定项目的依赖库,可以是本地文件系统、远程Maven仓库或者其他自定义仓库。 3. buildTypes:用于指定项目的构建类型,例如debug、release等。 4. productFlavors:用于指定项目的产品风味,例如free、paid等。 5. compileSdkVersion、buildToolsVersion、minSdkVersion、targetSdkVersion等:用于指定项目的编译版本、构建工具版本、最低支持版本和目标版本等。 以上是Android StudioGradle配置的基础内容,具体配置还需要根据项目需求进行调整。 ### 回答2: GradleAndroid Studio的一种构建工具,用于编译、打包、发布Android应用程序。它使用Groovy语言编写,基于Apache Maven和Apache Ant构建工具的优点,支持灵活的构建脚本并提供了丰富的插件,可以有效地管理依赖关系、自动化构建任务、自动导入库等。 在Android StudioGradle配置分为两部分:项目级别的Gradle配置和模块级别的Gradle配置。 项目级别的Gradle配置包括build.gradle文件和gradle-wrapper.properties文件。build.gradle文件是Gradle构建脚本的主文件,它定义了项目的构建方式、仓库地址、插件,以及需要构建的模块等。gradle-wrapper.properties文件是Gradle包装器的配置文件,它定义了Gradle版本号并指定了Gradle下载地址。 模块级别的Gradle配置包括build.gradle文件和proguard-rules.pro文件。build.gradle文件包括了该模块的构建配置,包括依赖库、运行时权限、签名方式,以及生成的APK路径等。proguard-rules.pro文件是混淆规则文件,它包括了混淆代码时需要忽略的类和方法等信息。 要配置Gradle,我们需要根据实际需要添加或修改相应的内容。例如,添加依赖库可以在build.gradle文件的dependencies节点添加相关依赖库信息,例如: implementation 'com.android.support:appcompat-v7:28.0.0' 如果需要修改混淆规则,可以在proguard-rules.pro文件添加相关规则,例如: -keep class com.example.app.** { *;} 总之,Gradle是一款功能强大的构建工具,它可以帮助开发者自动化构建任务,管理依赖关系等。对于Android开发者而言,掌握Gradle配置是非常重要的技能,可以提高开发效率,降低开发成本。 ### 回答3: Android Studio是一种支持Android应用程序开发的集成开发环境,而Gradle则是一种基于Apache Maven和Ant的开源构建自动化工具。它可以更轻松地以面向对象的方式来管理Java工程。在Android Studio,使用Gradle配置可以使项目更加方便,同时也具备了灵活性。 首先,我们需要了解一些Android StudioGradle配置的基本知识。可以在项目的根目录下找到build.gradle文件,这是Gradle构建脚本文件的主要文件之一。它包含了项目构建所需的所有配置信息,如编译版本号、依赖项等。在Gradle构建脚本,有两个重要的部分称为buildscript和dependencies。 buildscript: buildscript的配置项是为了配置Gradle的编译环境。通常包含如下的内容: - repositories: Gradle插件库和第三方库的URL地址。 - dependencies: Gradle插件列表,所有的插件都需要在这个部分声明,基本上最常见的就是com.android.tools.build:gradle。 dependencies: dependencies部分包含项目依赖的所有库文件,例如支持库和第三方库。我们可以通过在dependencies块添加依赖项来设置库和版本: 例如: ``` dependencies { compile 'com.android.support:appcompat-v7:26.0.0-beta1' compile 'com.android.support.constraint:constraint-layout:1.0.2' } ``` 此外,我们还可以更改项目编译版本。可以在build.gradle文件修改编译版本信息,例如minSdkVersion,targetSdkVersion和compileSdkVersion。以下是一个示例: ``` android { compileSdkVersion 27 defaultConfig { minSdkVersion 19 targetSdkVersion 27 ... } buildTypes { release { ... } } } ``` 在配置Gradle时,我们还可以添加自定义任务。Gradle提供了一组系统任务,例如clean,assemble,build和check等。我们也可以使用Gradle插件以及自定义任务来自己指定相关任务。 总之,配置Gradle可以使Android Studio更加灵活,能够更好地管理、构建和部署项目。通过使用Gradle构建脚本,我们可以更方便地进行依赖项管理以及其他任务。同时,它还支持自定义插件和扩展,以满足我们的特定需求。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值