Gradle多渠道打包

时间不会辜负每一个平静努力的人!

欢迎来到周建的博客: 共同致力于技术分享与交流

配置Gradle环境变量

如何配置Gradle环境变量,请参考我的另一篇博客:

Mac下配置Gradle环境变量
Windows用户配置Gradle环境变量应该也差不多,在这里就不介绍了

如果电脑上不单独配置Gradle环境也没关系,因为Android Studio使用了Gradle Wrapper,它可以在没有配置Gradle环境变量的情况下构建项目

Gradle Wrapper

  • Gradle Wrapper是什么?
    可以理解为对Gradle的一层封装,使用它可以在没有安装Gradle的系统上使用Gradle来构建项目

  • 如何做到的?
    Gradle Wrapper通过两个脚本文件实现这一功能,一个是用于windows的批处理文件gradlew.bat,一个是用于Linux和Uninx的Shell脚本文件gradlew.

使用Android Studio创建的项目默认为我们生成了Gradle Wrapper的文件结构.

a.png

在gradle/wrapper目录下有两个文件: gradle-wrapper.jar和gradle-wrapper.properties

gralde-wrapper.properties文件中声明了gradle的版本和下载地址.

1
2
3
4
5
6
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

在第一次使用gradlew进行项目构建的时候,Gradle Wrapper会自动下载gralde-wrapper.properties指定的gradle版本.

初始化构建环境

在第一次使用gradlew进行项目构建的时候,会对构建环境进行初始化,会把Gradle的安装包、插件和相关依赖下载下来.

在Terminal中输入命令,如下:
./gradlew clean

b.png

首次执行命令行会先去下载gradle安装包,过程可能会非常慢(耐心等待。。还是可以下载下来的)

如果实在太慢,可以设置代理去翻墙

常用Gradle任务

1.查看gradle版本
./gradlew -v

2.编译并打出Debug版本的包.
./gradlew assembleDebug

3.编译并打出Release版本的包.
./gradlew assembleRelease

4.执行检查并编译打包,打出所有Release和Debug的包.
./gradlew build

5.删除build目录,会把app下面的build目录删掉
./gradlew clean

6.编译打包并安装Debug版本的包
./gradlew installDebug

7.卸载Debug版本的包
./gradlew uninstallDebug

8.使用-info查看任务详情
./gradlew uninstallDebug -info

Gradle多渠道打包

在AndroidMainfest.xml配置相应的渠道

1
2
<meta-data android:value="UMENG_CHANNEL"
android:name="${UMENG_CHANNEL_VALUE}"/> <!--动态更改渠道号-->

在build.gradle中配置渠道信息和自动替换脚本

1
2
3
4
5
6
7
8
9
10
11
12
//多渠道打包
productFlavors {
xiaomi {}
huawei {}
yingyongbao {}
wandoujia {}
}
//自动替换清单文件中的渠道号
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}

默认配置

所有渠道默认使用这一配置,如果渠道有特殊需求,可以在productFlavors对应的渠道号中单独配置.

1
2
3
4
5
6
7
8
9
defaultConfig {
applicationId "com.zhoujian.buglydemo"
minSdkVersion 11
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true //突破应用方法数65535的限制
}

打包后自动修改apk的名字

release包的命名格式为:产品名版本号渠道名.apk

debug包的命名格式为:产品名_版本号-debug.apk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (null != outputFile && outputFile.name.endsWith('.apk')) {
File outputDir = new File(outputFile.parent);
def baseName = PRODUCT_NAME + "${defaultConfig.versionName}" + "_" + variant.productFlavors[0].name
def newApkName
if (variant.buildType.name.equals('release')) {
newApkName = baseName + '.apk'
} else if (variant.buildType.name.equals('debug')) {
def debugName = PRODUCT_NAME + "${defaultConfig.versionName}"
newApkName = debugName + "-debug.apk"
}
output.outputFile = new File(outputDir, newApkName)
}
}
}

我的build.gradle的完整文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
apply plugin: 'com.android.application'
//产品名
def PRODUCT_NAME = "BuglyDemo"
android {
//添加签名文件配置
signingConfigs {
mysigns {
keyAlias 'zjandroid'
keyPassword '123456'
storeFile file('/Users/zhoujian/AndroidStudioProjects/BuglyDemo/zhoujian.jks')
//storeFile file('zhoujian.jks')
storePassword '123456'
}
}
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.zhoujian.buglydemo"
minSdkVersion 11
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true //突破应用方法数65535的限制
}
//多渠道打包
productFlavors {
xiaomi {}
huawei {}
yingyongbao {}
wandoujia {}
}
//自动替换清单文件中的渠道号
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
buildTypes {
release {
minifyEnabled false //是否启用混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable false
jniDebuggable false
signingConfig signingConfigs.mysigns
renderscriptDebuggable false
minifyEnabled false
pseudoLocalesEnabled false
zipAlignEnabled true
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (null != outputFile && outputFile.name.endsWith('.apk')) {
File outputDir = new File(outputFile.parent);
def baseName = PRODUCT_NAME + "${defaultConfig.versionName}" + "_" + variant.productFlavors[0].name
def newApkName
if (variant.buildType.name.equals('release')) {
newApkName = baseName + '.apk'
} else if (variant.buildType.name.equals('debug')) {
def debugName = PRODUCT_NAME + "${defaultConfig.versionName}"
newApkName = debugName + "-debug.apk"
}
output.outputFile = new File(outputDir, newApkName)
}
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
testCompile 'junit:junit:4.12'
//添加友盟统计库依赖
compile 'com.umeng.analytics:analytics:latest.integration'
}

命令行打包

本文是以小米市场、华为市场、应用宝市场、豌豆荚市场为例

  • 打出debug包
    ./gradlew assembleDebug

a.png

  • 打出所有渠道的Release包
    ./gradlew assembleRelease

b.png

  • 打出小米市场的Release包

c.png

  • 同理,如果要打出华为市场的Release包
    ./gradlew assembleHuaweiRelease

d.png

  • 同时打出豌豆荚市场的debug包和Release包
    ./gradlew assembleWandoujia

e.png

Gradle多渠道打包出现的问题

如果在打包过程中出现问题,请参考我的另外两篇博客,有可能也是您遇到的问题:

Gradle打包:Keystore not found for signing config

Could not get unknown property ‘mysigns’ for SigningConfig container.