Android官方多渠道方案详解

栏目: Android · 发布时间: 6年前

内容简介:实际应用开发中,不可避免的会接触到多渠道打包,不过其实大家常用的多渠道打包其实分为两种。第一:只是需要简单的渠道标识,然后通过标识代码里做一些必要的逻辑处理,这种情况现在网上有很多开源的方案,可以做到快速打包,这里就不在多做介绍了。第二:需要对代码、资源、依赖、配置等做到更深度的定制,比如为不同的应用市场设置不同的启动页和简单总结下这两种方案,第一种打包速度快,但是不够灵活,第二种有很强的定制性,但是由于每次回重新编译并签名所以在打包速度上慢很多,大家可以根据需求自由选择不同的方案,或者搭配使用。首先需要

实际应用开发中,不可避免的会接触到多渠道打包,不过其实大家常用的多渠道打包其实分为两种。第一:只是需要简单的渠道标识,然后通过标识代码里做一些必要的逻辑处理,这种情况现在网上有很多开源的方案,可以做到快速打包,这里就不在多做介绍了。第二:需要对代码、资源、依赖、配置等做到更深度的定制,比如为不同的应用市场设置不同的启动页和 logo ,这种情况就可以采用官方的 ProductFlavors ,下面也会详细介绍这种方案。

简单总结下这两种方案,第一种打包速度快,但是不够灵活,第二种有很强的定制性,但是由于每次回重新编译并签名所以在打包速度上慢很多,大家可以根据需求自由选择不同的方案,或者搭配使用。

方案介绍

构建配置

首先需要在 module 中的 build.gradle 配置你需要的渠道,渠道中可以修改一些 defaultConfig 中的配置

android {
    ···
    defaultConfig {
        minSdkVersion 19
        versionCode 1
        ...
    }
    
    // 渠道的维度,支持不同维度的渠道
    flavorDimensions "channel"
    productFlavors {
        common {
            dimension "channel"
        }
        xiaomi {
            minSdkVersion '21'
            versionCode 20000  + android.defaultConfig.versionCode
            versionNameSuffix "-minApi21"
            dimension "channel"
        }
        huawei {
            minSdkVersion '23'
            versionCode 20000  + android.defaultConfig.versionCode
            versionNameSuffix "-minApi23"
            dimension "channel"
        }
    }
    
    buildTypes {
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

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

复制代码

Gradle 会通过上面的配置创建维度 * 维度中的渠道 * 构建类型数量的构建变体。在 Gradle 为对应构建变体的APK 命名时,首先是渠道,之后是构建类型。以上面的构建配置为例,Gradle 可以使用以下命名方案创建共6个构建变体:

构建变体: [common, xiaomi, huawei][debug, release]
对应 APK: app-[common, xiaomi, huawei]-[debug, release].apk

过滤变体

Gradle 会为每个可能的组合创建构建变体。都在 Android Studio -> Build Variants 中显示出来,不过某些特定的构建变体在您的项目环境中并不必要,也可能没有意义。您可以在 build.gradle 文件中创建一个变体过滤器,以移除某些构建变体配置。

android {
    ···
    variantFilter { variant ->
        def names = variant.flavors*.name
        def buildTypeName = variant.buildType.name
        println (names + "==" + buildTypeName)
        // 这样就会移除 commonDebug的变体
        if (buildTypeName.contains("debug") && names.contains("common")) {
            setIgnore(true)
        }
    }
    ...
}

复制代码

dependencies依赖

现实场景中有的时候不同的渠道,提供的功能也不尽相同,这样就需要对不同的渠道引入不同的组件包(前提App已经进行了组件拆分),如下简单配置就可以实现

configurations {
    // Gradle没有提供此细粒度级别的依赖方式,需要自己配置下不然会报错
    xiaomiDebugImplementation {}
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation('com.android.support:appcompat-v7:26.1.0')

    // 可以控制 xiaomi渠道下 的 debug 构建类型才去引入此包
    xiaomiDebugImplementation('com.xxx:xxx:1.6.0')
    debugImplementation('com.xxx:xxx:1.6.0')
    commonImplementation('com.xxx:xxx:1.6.0')
}
复制代码

不同渠道的独立签名

同上面需求,对于功能不同的安装包,大概率是要独立的签名,通过简单的配置一样可以实现,不过对于 debug 的构建类型,是不支持定制签名的,具体原因未知...

signingConfigs {
    test11 {
        storeFile file("../test11.keystore")
        storePassword 'test11'
        keyAlias 'test11'
        keyPassword 'test11'
    }
    test22 {
        storeFile file("../test22.keystore")
        storePassword 'test22'
        keyAlias 'test22'
        keyPassword 'test22'
    }
}
// 渠道的维度,支持不同维度的渠道
flavorDimensions "channel"
productFlavors {
    common {
        dimension "channel"
    }
    xiaomi {
        dimension "channel"
    }
    huawei {
        dimension "channel"
    }
}
buildTypes {
    debug {
        //debug定制签名无效 只能指定一个或者使用默认的签名
//            productFlavors.huawei.signingConfig signingConfigs.test11
//            productFlavors.xiaomi.signingConfig signingConfigs.test22
//            productFlavors.common.signingConfig signingConfigs.test11
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

    }
    release {
        productFlavors.huawei.signingConfig signingConfigs.test11
        productFlavors.xiaomi.signingConfig signingConfigs.test22
        productFlavors.common.signingConfig signingConfigs.test11
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
复制代码

Manifest配置

有时我们需要对 Mainfest 中的某个属性值做些调整,如配置不同渠道数据,App的Icon,还有替换声明Activity等等,都可以通过下面的配置实现,如果感觉这种简单的调整还不足以满足你的需求,可以看下方的定制源集的方案去深度的定制

// build.gradle
android {
    ···
    flavorDimensions "channel"
    productFlavors {
        common {
            dimension "channel"
            manifestPlaceholders = ["ChannelData" : "Common Meta Data",
                                    "AppIcon"     : "@mipmap/ic_common",
                                    "MainActivity":CommonActivity"]
        }
        xiaomi {
            dimension "channel"
            manifestPlaceholders = ["ChannelData" : "XiaoMi Meta Data",
                                    "AppIcon"     : "@mipmap/ic_launcher",
                                    "MainActivity":"XMActivity"]
        }
        huawei {
            dimension "channel"
            manifestPlaceholders = ["ChannelData" : "HuaWei Meta Data",
                                    "AppIcon"     : "@mipmap/ic_launcher",
                                    "MainActivity": "HWActivity"]
        }
    }
    ...
}

// Manifest 
<application
    //${AppIcon} 替换AppIcon
    android:icon="${AppIcon}"
    ... >

    //${ChannelData} 替换ChannelData
    <meta-data
        android:name="ChannelData"
        android:value="${ChannelData}"/>

    //${ChannelData} 替换声明Activity
    <activity android:name="${MainActivity}">
        ...
    </activity>
</application>



复制代码

定制代码 资源 Manifest 等源集

有时候简单的调整可能不足以解决实际问题,这个时候可以直接定制源集解决问题,找到 youModule\src ,当前目录下有个 main 文件夹为我们工程的核心代码和资源,我们可以在同级下创建不同的渠道目录,如: common``xiaomi 等,此目录可以放置自定义的 java代码res资源AndroidManifestassets 等。

不同变体目录(按优先级排列):

src/commonDebug/(构建变体源集)
src/debug/(buildTypes源集)
src/common/(productFlavors源集)
src/main/(主源集)
复制代码

上面列出的顺序决定了在 Gradle 合并代码和资源时哪个源集具有较高的优先级。如果 commonDebug/debug/ 包含相同的文件,Gradle 将使用 commonDebug/ 源集中的文件。同样,Gradle 会为其他源集中的文件赋予比 main/ 中相同文件更高的优先级。Gradle 在应用以下构建规则时会考虑此优先级顺序:

  • 对于 java/ 下的源代码只能有单一的类文件
    注:对于给定的渠道目录,如果找到两个或两个以上定义同一 Java 类的源集目录,Gradle 就会引发一个构建错误。例如,在构建调试 APK 时,您不能同时定义 src/common/Utility.javasrc/main/Utility.java 。这是因为 Gradle 会在构建过程中检查这两个目录并引发 duplicate class 错误。如果针对不同的构建类型需要不同版本的 Utility.java ,您可以让每个渠道定义其自己的文件版本,如: src/common/Utility.javasrc/xiaomi/Utility.java ,而不将其包含在 main/ 中。
  • 所有 Manifest 合并为单个 Manifest 。将按照上述列表中的相同顺序指定优先级。也就是说,某个构建类型的 Manifest 设置会替换某个渠道的 Manifest 设置
  • 同样, values/ res/ 和 asset/ 目录中的如果存在有两个或两个以上的同名资源,比如在渠道中的资源将会替换main中资源,以下对于同时存在于 strings.xml 的同名资源和资源图标做个示例
// main 下的 图标资源
main\res\mipmap-hdpi\ic_launcher.png

// 在 xiaomi 下的 图标资源
xiaomi\res\mipmap-hdpi\ic_launcher.png 

//打包 xiaomi 渠道的时候会自动替换图片。
复制代码
// main 下的 strings.xml
<resource>
    <string name="app_name">MultiChannel</string>
    <string name="string_merge">我是string,没被合并</string>
</resource>
// 在 xiaomi 下的 strings.xml 内容为:
<resource>
    <string name="string_merge">我是xiaomi,已经合并</string>
</resource>
//当打 xiaomi 渠道包时,最终 strings.xml 会变成:
<resource>
    <string name="app_name">MultiChannel</string>
    <string name="string_merge">我是xiaomi,已经合并</string>
</resource>
复制代码

其他

命令构建

对于习惯于使用命令构建的同学来说有以下几点需要补充

  • 打全部包: gradle assemble
  • 打全部 Debug 包: gradle assembleDebug ,可以简写为 gradle aD 或 aDebug
  • 打全部 Release 包: gradle assembleRelease,可以简写为 gradle aR 或 aRelease
  • 打指定 flavor 包: gradle assemble(flavor)(Debug|Release) 如:gradle assembleXiaomiDebug
  • 打包完成后安装: gradle install(flavor)(Debug|Release)如:如:gradle installXiaomiDebug
  • 打包前先 clean 一下,在测试的时候很必要: gradle clean assembleXiaomiDebug

参考阅读


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python编程快速上手

Python编程快速上手

Albert Sweigart / 王海鹏 / 人民邮电出版社 / 2016-7-1 / 69.00元

如今,人们面临的大多数任务都可以通过编写计算机软件来完成。Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。通过Python编程,我们能够解决现实生活中的很多任务。 本书是一本面向实践的Python编程实用指南。本书的目的,不仅是介绍Python语言的基础知识,而且还通过项目实践教会读者如何应用这些知识和技能。本书的首部分介绍了基本Python编程概念,第二部分介绍了一些不......一起来看看 《Python编程快速上手》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具