Gradle配置3

多渠道打包

创建渠道占位符

首先在AndroidMainifest文件的Application节点下,创建如下所示的meta-date节点。

<meta-data
            android:name="PRODUCT"
            android:value="${CHANNEL_VALUE}"/>

其中”${CHANNEL_VALUE}”就是要进行替换的渠道占位符。

配置gradle脚本

在项目的gradle脚本的android领域中,添加productFlavors领域,并增加定义的渠道名。同时,使用manifestPlaceholders指定要替换渠道占位符的值,代码如下:

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        xys{
            signingConfig signingConfigs.xys
        }
    }

    productFlavors{
        xiaomi{
            manifestPlaceholders = [CHANNEL_VALUE:"XIAOMI"]
        }
        wandujia {
            manifestPlaceholders = [CHANNEL_VALUE:"WANDUJIA"]
        }
    }

定义了两种不同的渠道,——xiaomi、wandoujia。每个渠道都将指定值赋给渠道占位符CHANNEL_VALUE。这样配置后,就完成了整个多渠道打包工作。生成的apk如下:
这里写图片描述
每个渠道包都有三种:debug、release(系统默认的两种buildType)和xys(自定义的buildType)。

脚本优化

熟悉groovy语言之后,可以对以上脚本进行优化:

productFlavors{
        xiaomi{}
        wandujia {}
    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders=[CHANNEL_VALUE:name]
    }

生成重命名包名

在生成渠道包名后,包的命名通常是默认命名,即app-渠道名-buildType.apk。
但是有时候我们需要自定义apk包名,这时就可以通过gradle脚本进行快速重命名,代码如下:

android {
   buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        xys{
            signingConfig signingConfigs.xys
        }
    }

    productFlavors{
        xiaomi{}
        wandujia {}
    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders=[CHANNEL_VALUE:name]
    }

    applicationVariants.all{ variant->
        variant.outputs.each { output ->
            if (output.outputFile != null && output.outputFile.name.endsWith(".apk")) {
                if ('release'.equals(variant.buildType.name)) {
                    def apkFile = new File(output.outputFile.getParent(),
                            "releaseApp_${variant.flavorName}_v${variant.versionName}.apk")
                    output.outputFile = apkFile
                }
                if ('xys'.equals(variant.buildType.name)) {
                    def apkFile = new File(output.outputFile.getParent(),
                            "xysApp_${variant.flavorName}_v${variant.versionName}.apk")
                    output.outputFile = apkFile
                }
                if ('debug'.equals(variant.buildType.name)) {

                }
            }

        }

    }
}

这段代码的意思是取出所有的生成的apk包,并判断其文件是否是apk、是否是release、xys版本。如果是,则重新命名为“buildType名App_渠道名_v版本号.apk”。如下:
这里写图片描述
因为debug类型没有进行重命名,所以它的apk包名还是以前的。

为不同的版本添加不同的代码

在开发中,不同的版本通常有不同的代码功能。例如最常用的Log开关,在debug版本中会打印开发日志,而在release版本中是需要关闭的。因此,一般会有一个全局的变量开关,根据不同的版本设置不同的值。这一切在gradle脚本的支持下,仅仅变成了一句配置。以buildType为例,为不同的buildType添加不同的参数配置,代码如下所示:

buildTypes {
        release {
            buildConfigField("boolean", "testFlag", "true")
            minifyEnabled false
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        xys{
            buildConfigField("boolean", "testFlag", "false")
            signingConfig signingConfigs.xys
        }
    }

通过指定buildConfigField的三个参数——类型、名称、值,就可以将一个变量设置到不同的buildType中去。打开系统的BuildConfig类,可以看到不同的buildType下对应的testFlag的值。该文件对应的路径为/项目/app/build/generated/source/buildConfig/,内容如下:

public final class BuildConfig {
  public static final boolean DEBUG = false;
  public static final String APPLICATION_ID = "com.example.administrator.demo";
  public static final String BUILD_TYPE = "release";
  public static final String FLAVOR = "wandujia";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from build type: release
  public static final boolean testFlag = true;
}
public final class BuildConfig {
  public static final boolean DEBUG = false;
  public static final String APPLICATION_ID = "com.example.administrator.demo";
  public static final String BUILD_TYPE = "xys";
  public static final String FLAVOR = "wandujia";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from build type: xys
  public static final boolean testFlag = false;
}

如果是string类型的变量,在写入字符串的时候,需要加入转义字符。

buildConfigField("String", "testFlag", "\"abc\"")

也可以在设置变量的时候,继续使用变量,如下:

buildConfigField("String", "testFlag", "\"${param}\"")
def param = ···

除了java代码可以使用这种方式进行添加之外,资源文件同样可以进行分版本设置属性值。例如要给不同的版本设置不同的AppName,通过gradle同样是仅仅一行配置即可实现。
在buildType的release和xys这两个Type中进行设置resValue,添加如下所示代码:

buildTypes {

        release {
            resValue("string", "app_name", "AppRelease")
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        xys{
            resValue("string", "app_name", "AppXys")
            signingConfig signingConfigs.xys
        }
    }

同时在defaultConfig领域中添加默认的配置,代码如下:

defaultConfig {
        applicationId "com.example.administrator.demo"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        resValue("string", "app_name", "App")
    }

在AndroidMainfest文件中,同样使用android:label=”@string/app_name”来获取app_name,但是要注意的是,一定要把string.xml文件中的Demo删掉,这样才能编译过。因为gradle在编译过程中会将脚本中的配置和string.xml文件中的配置进行merge操作,如果同时存在两份相同的属性值,就会发生冲突。

另外resValue配置的参数,不一定非要替换代码中的占位,还可以直接增加变量到R文件中。


def buildTime() {
    return new Date().format("yyyy-MM-dd HH:mm:ss")
}

defaultConfig {
        resValue("string", "build_time", buildTime())
    }

在上面的代码中,定义了一个buildTime方法,并赋值给自定义的build_time变量。这时候不需要在java代码中增加变量,即可直接引用已经编译到R文件中的变量build_time,代码如下:

Log.d("-->", getString(R.string.build_time));

打印结果:

01-08 22:51:50.403 19532-19532/com.example.administrator.demo D/-->: 2017-01-08 22:50:45
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值