多渠道打包

国内Android应用下载有360、小米、豌豆荚、百度等等非常多的渠道, 如果我们想统计每个渠道的下载量和活跃度,就需要使用统计平台.

我们以友盟统计为例,介绍如何配置渠道信息并执行自动化打包.

1.在AndroidMainfest.xml配置可动态替换的渠道参数

友盟集成文档中有说明,使用友盟统计需要在AndroidMainfest.xml配置相应的渠道号:

<meta-data

 android:name="UMENG_CHANNEL"

 android:value="xiaomi" /><!--渠道号为:小米-->

如果想动态的替换渠道号怎么办呢?

<meta-data

android:name="UMENG_CHANNEL"

android:value="${CHANNEL_ID}" /><!--动态替换渠道号-->

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

// 多渠道打包

productFlavors {

 xiaomi {} //渠道名name为xiaomi

 baidu {}

 wandoujia {}



 // 自动替换AndroidManifest.xml中的渠道号

 productFlavors.all { flavor ->

 flavor.manifestPlaceholders = [CHANNEL_ID: name]

 }

}

配置好以后在Build Variants窗口中可以选择不同渠道的变种版本:

Gradle工具栏也会生成相应的任务:

3.默认配置

// 默认配置

defaultConfig {

 applicationId "com.wirelessqa.basebuildsample" //apk包名

 minSdkVersion 16

 targetSdkVersion 23

 versionCode 1

 versionName "1.0" //版本号

 //android单元测试test runner

 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

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

4.打包后自动修改apk的名字

// 打包后自动修改apk的名字

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

// debug包的命名格式为:产品名_版本号_渠道号_Debug_打包时间.apk

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')) {

 newApkName = baseName + "_Debug_${packageTime()}.apk"

 }



 output.outputFile = new File(outputDir, newApkName)

 }

 }



}

5.自动化打包

如何一次打出所有渠道的Release的包呢?

方法一: 命令行:

$ ./gradlew assembleRelease

方法二: Gradle工具窗口:

方法三: 菜单栏 —> Build —> Generate Signed APK —> 一步步下去 —> Flavors中全选—> Finish.

这样所有渠道的Release包都被打出来了.

6.查看渠道号是否被正确替换.

单击apk之后,Android Studio会自动解析apk,这样我们就可以在Android Studio中直接查看apk的信息了.

1.单击baidu这个渠道 —>2.点击AndroidManifest.xml —>3.查看渠道号为baidu

由此证明我们的打包脚本是OK的.

如果要打Debug包,执行assembleDebug任务就可以了.

如果只想打某一个渠道的包,执行对应的打包任务就可以了.

本例中全部的build.gradle脚本如下:

//插件:

//这个module是一个android程序,使用com.android.application

//如果是android库,应该使用com.android.library

apply plugin: 'com.android.application'



//产品名

def PRODUCT_NAME = "wirelessqa"

//打包时间

def packageTime() {

 return new Date().format("MMddhhmmss", TimeZone.getTimeZone("GMT+8"))

}



android {



// 签名配置

signingConfigs {

 MySigning {

 keyAlias 'myandroid'

 keyPassword '123456'

 storeFile file('/Users/bixiaopeng/myandroid.jks')

 storePassword '123456'

 }

}

// 编译sdk版本

compileSdkVersion 23

// 构建工具版本

buildToolsVersion "23.0.2"



// 默认配置

defaultConfig {

 applicationId "com.wirelessqa.basebuildsample" //apk包名

 minSdkVersion 16

 targetSdkVersion 23

 versionCode 1

 versionName "1.0" //版本号

 //android单元测试test runner

 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

 versionNameSuffix 'test'

}



// 产品特性

productFlavors {

 xiaomi {} //渠道名name为xiaomi

 baidu {

 }

 wandoujia {}

 // 自动替换AndroidManifest.xml中的渠道号

 productFlavors.all { flavor ->

 flavor.manifestPlaceholders = [CHANNEL_ID: name]

 }

}



// 构建类型,此处配置debug和release版本的一些参数,像混淆、签名配置.

buildTypes {

 // release包的配置

 release {

 //开启混淆

 minifyEnabled true

 // 指定混淆文件

 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

 // 指定签名配置

 signingConfig signingConfigs.MySigning

 zipAlignEnabled true

 //移除无用的资源文件

 shrinkResources true

 }

}



// 打包后自动修改apk的名字

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

// debug包的命名格式为:产品名_版本号_渠道号_Debug_打包时间.apk

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')) {

 newApkName = baseName + "_Debug_${packageTime()}.apk"

 }



 output.outputFile = new File(outputDir, newApkName)

 }

 }



 }

}



// 依赖的第三方库

dependencies {

 compile fileTree(include: ['*.jar'], dir: 'libs')

 compile 'com.android.support:appcompat-v7:23.4.0'

 compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha1'

 compile 'com.android.support:design:23.4.0'

 testCompile 'junit:junit:4.12'

 androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'

 androidTestCompile 'com.android.support.test:runner:0.5'

 androidTestCompile 'com.android.support:support-annotations:23.4.0'

}

results matching ""

    No results matching ""