• 多渠道打包
    • 1.在AndroidMainfest.xml配置可动态替换的渠道参数
    • 2.在build.gradle中配置渠道信息和自动替换脚本
    • 3.默认配置
    • 4.打包后自动修改apk的名字
    • 5.自动化打包
    • 6.查看渠道号是否被正确替换.

    多渠道打包

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

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

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

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

    1. <meta-data
    2. android:name="UMENG_CHANNEL"
    3. android:value="xiaomi" /><!--渠道号为:小米-->

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

    1. <meta-data
    2. android:name="UMENG_CHANNEL"
    3. android:value="${CHANNEL_ID}" /><!--动态替换渠道号-->

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

    1. // 多渠道打包
    2. productFlavors {
    3. xiaomi {} //渠道名name为xiaomi
    4. baidu {}
    5. wandoujia {}
    6. // 自动替换AndroidManifest.xml中的渠道号
    7. productFlavors.all { flavor ->
    8. flavor.manifestPlaceholders = [CHANNEL_ID: name]
    9. }
    10. }

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

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

    3.默认配置

    1. // 默认配置
    2. defaultConfig {
    3. applicationId "com.wirelessqa.basebuildsample" //apk包名
    4. minSdkVersion 16
    5. targetSdkVersion 23
    6. versionCode 1
    7. versionName "1.0" //版本号
    8. //android单元测试test runner
    9. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    10. }

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

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

    1. // 打包后自动修改apk的名字
    2. // release包的命名格式为:产品名_版本号_渠道号.apk
    3. // debug包的命名格式为:产品名_版本号_渠道号_Debug_打包时间.apk
    4. applicationVariants.all { variant ->
    5. variant.outputs.each { output ->
    6. def outputFile = output.outputFile
    7. if (null != outputFile && outputFile.name.endsWith('.apk')) {
    8. File outputDir = new File(outputFile.parent);
    9. def baseName = PRODUCT_NAME + "${defaultConfig.versionName}" + "_" + variant.productFlavors[0].name
    10. def newApkName
    11. if (variant.buildType.name.equals('release')) {
    12. newApkName = baseName + '.apk'
    13. } else if (variant.buildType.name.equals('debug')) {
    14. newApkName = baseName + "_Debug_${packageTime()}.apk"
    15. }
    16. output.outputFile = new File(outputDir, newApkName)
    17. }
    18. }
    19. }

    5.自动化打包

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

    方法一: 命令行:

    1. $ ./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脚本如下:

    1. //插件:
    2. //这个module是一个android程序,使用com.android.application
    3. //如果是android库,应该使用com.android.library
    4. apply plugin: 'com.android.application'
    5. //产品名
    6. def PRODUCT_NAME = "wirelessqa"
    7. //打包时间
    8. def packageTime() {
    9. return new Date().format("MMddhhmmss", TimeZone.getTimeZone("GMT+8"))
    10. }
    11. android {
    12. // 签名配置
    13. signingConfigs {
    14. MySigning {
    15. keyAlias 'myandroid'
    16. keyPassword '123456'
    17. storeFile file('/Users/bixiaopeng/myandroid.jks')
    18. storePassword '123456'
    19. }
    20. }
    21. // 编译sdk版本
    22. compileSdkVersion 23
    23. // 构建工具版本
    24. buildToolsVersion "23.0.2"
    25. // 默认配置
    26. defaultConfig {
    27. applicationId "com.wirelessqa.basebuildsample" //apk包名
    28. minSdkVersion 16
    29. targetSdkVersion 23
    30. versionCode 1
    31. versionName "1.0" //版本号
    32. //android单元测试test runner
    33. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    34. versionNameSuffix 'test'
    35. }
    36. // 产品特性
    37. productFlavors {
    38. xiaomi {} //渠道名name为xiaomi
    39. baidu {
    40. }
    41. wandoujia {}
    42. // 自动替换AndroidManifest.xml中的渠道号
    43. productFlavors.all { flavor ->
    44. flavor.manifestPlaceholders = [CHANNEL_ID: name]
    45. }
    46. }
    47. // 构建类型,此处配置debug和release版本的一些参数,像混淆、签名配置.
    48. buildTypes {
    49. // release包的配置
    50. release {
    51. //开启混淆
    52. minifyEnabled true
    53. // 指定混淆文件
    54. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    55. // 指定签名配置
    56. signingConfig signingConfigs.MySigning
    57. zipAlignEnabled true
    58. //移除无用的资源文件
    59. shrinkResources true
    60. }
    61. }
    62. // 打包后自动修改apk的名字
    63. // release包的命名格式为:产品名_版本号_渠道号.apk
    64. // debug包的命名格式为:产品名_版本号_渠道号_Debug_打包时间.apk
    65. applicationVariants.all { variant ->
    66. variant.outputs.each { output ->
    67. def outputFile = output.outputFile
    68. if (null != outputFile && outputFile.name.endsWith('.apk')) {
    69. File outputDir = new File(outputFile.parent);
    70. def baseName = PRODUCT_NAME + "${defaultConfig.versionName}" + "_" + variant.productFlavors[0].name
    71. def newApkName
    72. if (variant.buildType.name.equals('release')) {
    73. newApkName = baseName + '.apk'
    74. } else if (variant.buildType.name.equals('debug')) {
    75. newApkName = baseName + "_Debug_${packageTime()}.apk"
    76. }
    77. output.outputFile = new File(outputDir, newApkName)
    78. }
    79. }
    80. }
    81. }
    82. // 依赖的第三方库
    83. dependencies {
    84. compile fileTree(include: ['*.jar'], dir: 'libs')
    85. compile 'com.android.support:appcompat-v7:23.4.0'
    86. compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha1'
    87. compile 'com.android.support:design:23.4.0'
    88. testCompile 'junit:junit:4.12'
    89. androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
    90. androidTestCompile 'com.android.support.test:runner:0.5'
    91. androidTestCompile 'com.android.support:support-annotations:23.4.0'
    92. }