Android官方多渠道方案详解

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

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

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

参考阅读


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

查看所有标签

猜你喜欢:

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

Game Programming Patterns

Game Programming Patterns

Robert Nystrom / Genever Benning / 2014-11-2 / USD 39.95

The biggest challenge facing many game programmers is completing their game. Most game projects fizzle out, overwhelmed by the complexity of their own code. Game Programming Patterns tackles that exac......一起来看看 《Game Programming Patterns》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具