【Android】多渠道打包配置

目录

  • 简介
  • 打包配置
    • 签名配置
    • 渠道配置
    • 配置打包出来的App名称
    • 正式包与测试包配置
  • 打包方式
    • 开发工具打包
    • 命令行打包
  • 优缺点

简介

多渠道打包 是指在打包一个 Android 应用时,一次编译生成多个 APK 文件,每个 APK 文件针对一个特定的渠道。不同的渠道可能代表不同的应用商店、推广合作伙伴、地区等。每个渠道可能有不同的配置,例如不同的包名、资源、应用 ID、签名信息等。

打包配置

在打包之前,先聊一下我的需求。

我现在想打三个渠道的包,分别为 xiaomihuaweimeizu。通过多渠道打包的方式能够实现一次编译打三个包,且通过多渠道打包生成的包生成位置不同、包名不同的 App、AndroidManifest.xml 文件不同的包。

在 Android Studio 里,打包是由 Gradle 脚本去完成,因此,毫无疑问,以下的一些配置都是写在了 build.gradle 文件里。

由于 build.gradle 文件是从上往下执行的,因此,导入其它插件的代码一般写在最上面第一二行的位置。在 build.gradle 文件中,部分配置是有一个先后的执行顺序,就是说,他们的先后执行顺序如果错乱,就会出现各种奇怪的问题。

签名配置

多渠道打包 app 的签名配置在了 signingConfigs 里,分为了三个签名配置,分别是 xiaomiSigningConfigs huaweiSigningConfigs meizuSigningConfigs

android {
	. . .
	// 多渠道打包签名配置
    signingConfigs {
		// 配置 xiaomi 渠道的签名
        xiaomiSigningConfigs {
            storeFile file('../keystore/xiaomi.jks')
            storePassword '123456'
            keyAlias 'xiaomi'
            keyPassword '123456'
        }
		// 配置 huawei 渠道的签名
        huaweiSigningConfigs {
            storeFile file('../keystore/huawei.jks')
            storePassword '123456'
            keyAlias 'huawei'
            keyPassword '123456'
        }
		// 配置 meizu 渠道的签名
        meizuSigningConfigs {
            storeFile file('../keystore/meizu.jks')
            storePassword '123456'
            keyAlias 'meizu'
            keyPassword '123456'
        }
    }
    . . .
}

PS:填写 storeFile jks 文件配置时,需确认所在路径是否存在相应的 jks 文件,否则会在 Sync Now 或打包的时候出现某些奇奇怪怪的问题。

渠道配置

android {
	. . .
	// 配置渠道
    productFlavors {
        // xiaomi渠道
        xiaomi {
            // 配置与ndk相关的配置
            ndk {
                // 配置打包的安装包支持的设备架构
                abiFilters 'arm64-v8a', 'armeabi-v7a'
            }
            // 在包名后面添加包名的内容
            applicationIdSuffix '.xiaomi'
            // 替换strings.xml文件里对应名称的值
            resValue "string", "app_name", "@string/app_name_xiaomi"
            // 配置渠道打包所需的签名
            signingConfig signingConfigs.xiaomiSigningConfigs
        }
        // huawei渠道
        huawei {
            applicationIdSuffix '.huawei'
            ndk {
                abiFilters 'arm64-v8a', 'armeabi-v7a'
            }
            resValue "string", "app_name", "@string/app_name_huawei"
            signingConfig signingConfigs.huaweiSigningConfigs
        }
        // meizu渠道
        meizu {
            applicationIdSuffix '.meizu'
            ndk {
                abiFilters 'arm64-v8a', 'armeabi-v7a'
            }
            resValue "string", "app_name", "@string/app_name_meizu"
            signingConfig signingConfigs.meizuSigningConfigs
        }
    }
    . . .
}

PS:在渠道包配置里写了与签名相关的配置后,就不能够在 buildTypes 里写,否则会 buildTypes 的签名被覆盖,且打包时只能使用命令行打包,使用开发工具打包签名会被选择打包签名的那一个签名给覆盖掉。

配置打包出来的App名称

android {
	. . .
    // 配置各个渠道包打包出来的app名称
    def buildTime = buildTime()
    android.applicationVariants.configureEach { variant ->
    	// 根据渠道名称判断打的渠道包是什么
        if (variant.name.contains('xiaomi')) {
            variant.outputs.configureEach { output ->
	            // 修改打出来的包的名称
                output.outputFileName = "多渠道打包-xiaomi-${buildTime}.apk"
            }
        } else if (variant.name.contains('huawei')) {
            variant.outputs.configureEach { output ->
                output.outputFileName = "多渠道打包-huawei-${buildTime}.apk"
            }
        } else if (variant.name.contains('meizu')) {
            variant.outputs.configureEach { output ->
                output.outputFileName = "多渠道打包`-meizu-${buildTime}.apk"
            }
        }
    }
    . . . 
}

正式包与测试包配置

android {
	. . .
	// 配置buildTypes
    buildTypes {
        // 配置打release包时的配置
        release {
        	// 配置打release包时的签名(经过测试,无效果)
            signingConfig signingConfigs.xiaomiSigningConfigs
            debuggable false // 打出来的包是否包含调试信息
            minifyEnabled false  // 启用或禁用代码混淆
            shrinkResources false // 是否移除未使用的资源
            zipAlignEnabled true // 控制是否对apk进行优化
            testCoverageEnabled false // 是否启用代码覆盖率报告
            versionNameSuffix '-xiaomi' // 附加打包版本名称后缀
            multiDexEnabled true // 是否启用多dex支持(适用于方法数超过65536的应用)
            embedMicroApp false // 配置是否将微应用嵌入到主应用中
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        // 配置打debug包时的配置
        debug {
            signingConfig signingConfigs.xiaomiSigningConfigs
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    . . .
}

打包方式

开发工具打包

打开 Android Studio,在顶部菜单栏依次选择 Build 👉 Generate Signed App Bundle / Apk

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
打包可以选择多个渠道打包,快捷键为 Control + 鼠标左键 ,如下:

在这里插入图片描述
点击 Create 再过几分钟就会在 Module 下面生成对应的 app。
在这里插入图片描述

PS:使用 Android Studio 开发工具打包,多个app一起打包时,无法生成不同签名的app,最终打出来的app签名都会是同一个。

命令行打包

使用命令行打包前,需要提前配置好 Java 环境,并将其添加到系统的环境变量。

点击打开 Android StudioTerminal ,输入 ./gradlew 确定是否可以正常使用。

./gradlew

若已经完成多渠道的相关配置,继续执行 ./graldew tasks 查看可执行的命令,命令及执行结果如下:

./graldew tasks

在这里插入图片描述
上图的执行结果展示了可执行的任务,打所有渠道的正式包使用的是 assembleRelease 命令:

./graldew assembleRelease

执行完成如下图所示:
在这里插入图片描述
使用命令行打包不会提示打的包保存在了哪里,可以到该路径下查看 项目所在路径\csdn-demo\multi-channel-package\build\outputs\apk\

优缺点

优点

  • 通过多渠道打包,可以统一管理应用的不同版本,简化发布流程和后续维护。
  • 可以分别统计每个渠道的下载量、活跃用户、用户留存等数据,从而进行更精细的运营和推广。
  • 可以针对不同市场定制不同版本的应用,满足不同国家和地区的法律法规、文化习惯和用户需求。
  • 不同渠道可以使用不同的资源配置(如图标、启动页、应用名称等),满足不同市场或合作伙伴的需求。
  • 不同的合作伙伴可能有不同的要求,通过多渠道打包可以更好地满足他们的需求,从而提升合作伙伴的满意度。

缺点

  • 需要为不同渠道配置不同的资源和代码,增加了开发和维护的复杂度和工作量。
  • 需要管理多个市场和渠道的发布和更新,这可能导致市场碎片化和管理难度增加。
  • 不同渠道的资源配置可能会导致资源冗余,增大APK文件的体积,占用更多的存储空间。
  • 多渠道打包需要配置多个构建变体,构建和发布流程变得更复杂,需要更细致的管理和协调。
  • 不同渠道版本的应用可能存在差异,容易导致一些特定渠道版本出现质量问题,需要更多的测试和质量保证工作。

常见问题

  • Caused by: groovy.lang.MissingMethodException: No signature of method: java.lang.Integer.call() is applicable for argument types: (build_dnmb91jd12bvybe4o3deskrm1 r u n c l o s u r e 1 _run_closure1 runclosure1_closure4 c l o s u r e 10 ) v a l u e s : [ b u i l d d n m b 91 j d 12 b v y b e 4 o 3 d e s k r m 1 _closure10) values: [build_dnmb91jd12bvybe4o3deskrm1 closure10)values:[builddnmb91jd12bvybe4o3deskrm1_run_closure1 c l o s u r e 4 _closure4 closure4_closure10@5e0c18f1]
    解决办法:buildTypes 对象里的参数不能以数字命名。
  • Caused by: groovy.lang.MissingPropertyException: Could not get unknown property ‘xiaomiSigningConfigs’ for SigningConfig container of type org.gradle.api.internal.FactoryNamedDomainObjectContainer.
    解决办法:
    1、检查是否存在 xiaomiSigningConfigs 的配置。
    2、signingConfigs 的配置是否写在了 buildTypes 的下方。(由于 Gradle 编译顺序是从文件上往下编译的,如果 buildTypessigningConfigs 的上方,意味着 buildTypes 会先被编译,自然会出现这种找不到 signingConfigs 里面配置的问题)

参考文档

  • 配置 build 变体
  • Gradle 官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/902370.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Prompt提示词设计:如何让你的AI对话更智能?

Prompt设计:如何让你的AI对话更智能? 在人工智能的世界里,Prompt(提示词)就像是一把钥匙,能够解锁AI的潜力,让它更好地理解和响应你的需求。今天,我们就来聊聊如何通过精心设计的Pr…

厂房区域人员进出人数统计-实施方案

1.1 现状分析 传统的人流量统计方法往往依赖于人工计数或简单的视频监控系统,这些方法不仅效率低下,而且容易出错,无法满足现代仓库管理的需求。因此,我厂区决定引入先进的智能监控系统,通过集成高清摄像头、GPU服务器…

【Unity】仓库逻辑:拾取物体进仓库和扔掉物品

需求说明 目标:实现玩家移动过程中,拾取物体,物体被放入仓库;点击仓库中物体,重新扔回3D场景中逻辑。 逻辑分析: 需要玩家可以移动;需要检测玩家和物体的碰撞,并摧毁物体&#xf…

css知识点梳理2

1. 选择器拓展 在 CSS 中,可以根据选择器的类型把选择器分为基础选择器和复合选择器,复合选择器是建立在基础选择器之上,对基本选择器进行组合形成的。 ​ 复合选择器是由两个或多个基础选择器,通过不同的方式组合而成的&#xf…

【Flask】一、安装与第一个测试程序

目录 Flask简介 安装Flask 安装pip(Python包管理器) 使用pip安装Flask 验证安装 创建Flask程序 创建应用 运行 访问测试 Flask简介 Flask是一个用Python编写的轻量级Web应用框架。它被设计为易于使用和扩展,使其成为构建简单网站或复…

[项目][boost搜索引擎#4] cpp-httplib使用 | log.hpp | 前端 | 测试及总结

目录 编写http_server模块 1. 引入cpp-httplib到项目中 2. cpp-httplib的使用介绍 3. 正式编写http_server 九、添加日志到项目中 十、编写前端模块 十一. 详解传 gitee 十二、项目总结 项目的扩展 写在前面 项目 gitee 已经上传啦 (还是决定将学校和个人…

网络编程基础-Reactor线程模型-原理剖析

1、Reactor基本概念 Reactor线程模型其实是一种设计模式,其核心思想就是将输入多路复用和事件派发相结合,从而减少系统中活跃线程的数量。 像我们之前讲到的文章网络编程基础-IO模型深入理解_网络io-CSDN博客提到了其中网络IO模型(BIO、NIO…

asp.net core 入口 验证token,但有的接口要跳过验证

asp.net core 入口 验证token,但有的接口要跳过验证 在ASP.NET Core中,你可以使用中间件来验证token,并为特定的接口创建一个属性来标记是否跳过验证。以下是一个简化的例子: 创建一个自定义属性来标记是否跳过验证: public clas…

基于PHP的http字段查询与注册(V1)(持续迭代)

目录 版本说明: 实现环境(WAMP): 数据库链接 查询页面 php处理逻辑 字段添加 版本说明: 该查询功能以查询http首部字段为目的实现的字段属性、字段内容的查询,以及对新字段信息的数据注册。 v1实现…

python 制作 发货单 (生成 html, pdf)

起因, 目的: 某个小店,想做个发货单。 过程: 先写一个 html 模板。准备数据, 一般是从数据库读取,也可以是 json 格式,或是 python 字典。总之,是数据内容。使用 jinja2 来渲染模板。最终的结果可以是 h…

多线程进阶——线程池的实现

什么是池化技术 池化技术是一种资源管理策略,它通过重复利用已存在的资源来减少资源的消耗,从而提高系统的性能和效率。在计算机编程中,池化技术通常用于管理线程、连接、数据库连接等资源。 我们会将可能使用的资源预先创建好,…

WPF+MVVM案例实战(七)- 系统初始化界面字体描边效果实现

文章目录 1、案例效果展示2、项目准备3、功能实现1、资源获取2、界面代码3、后台代码 4 源代码获取 1、案例效果展示 2、项目准备 打开项目 Wpf_Examples,新建系统初始化界面 WelcomeWindow.xmal,如下所示: 3、功能实现 1、资源获取 案例中使用的CSD…

Java | Leetcode Java题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution {public int longestPalindromeSubseq(String s) {int n s.length();int[][] dp new int[n][n];for (int i n - 1; i > 0; i--) {dp[i][i] 1;char c1 s.charAt(i);for (int j i 1; j < n; j) {char c2 s.char…

【Java并发编程】信号量Semaphore详解

一、简介 Semaphore&#xff08;信号量&#xff09;&#xff1a;是用来控制同时访问特定资源的线程数量&#xff0c;它通过协调各个线程&#xff0c;以保证合理的使用公共资源。 Semaphore 一般用于流量的控制&#xff0c;特别是公共资源有限的应用场景。例如数据库的连接&am…

Python | Leetcode Python题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution:def longestPalindromeSubseq(self, s: str) -> int:n len(s)dp [[0] * n for _ in range(n)]for i in range(n - 1, -1, -1):dp[i][i] 1for j in range(i 1, n):if s[i] s[j]:dp[i][j] dp[i 1][j - 1] 2else:dp…

从病理AI的基础模型发展历程,看未来的医学AI发展趋势|个人观点·24-10-23

小罗碎碎念 在临床相关的人工智能&#xff08;AI&#xff09;模型发展方面&#xff0c;传统上需要大量标注数据集&#xff0c;这使得AI的进步主要围绕大型中心和私营企业展开。所以&#xff0c;在这期推文中&#xff0c;我会介绍一些已经商用的模型&#xff0c;并且为计划进军…

逻辑推理学习笔记

目的 立场辩护整理思绪 基本框架 论题 &#xff08;变化&#xff09; 我要证明&#xff08;讨论对象 变化&#xff09; 论据 &#xff08;变化&#xff09; 拿什么证明&#xff1f;也就是证据呈现。 论证 &#xff08;不变&#xff09; 要如何证明&#xff1f;逻辑框架…

通过conda install -c nvidia cuda=“11.3.0“ 安装低版本的cuda,但是却安装了高版本的12.4.0

问题 直接通过 conda install -c nvidia cuda"11.3.0"安装得到的却是高版本的 不清楚原理 解决方法 不过我们可以分个安装 runtime toolkit 和 nvcc 安装指定版本的 cudatoolkit 和 nvcc conda install -c nvidia cuda-cudart"11.3.58" conda instal…

【Linux系统编程】——Linux入门指南:从零开始掌握操作系统的核心(指令篇)

文章目录 查看 Linux 主机 ip以及登录主机Linux基础文件操作指令man&#xff1a;查看命令的手册页&#xff0c;了解命令的详细用法。pwd&#xff1a;显示当前目录路径。cd&#xff1a;切换目录。ls&#xff1a;列出当前目录下的文件和文件夹。mkdir&#xff1a;创建新目录。 文…

第三讲、C的运算符和表达式

一、运算符分类&#xff1a; &#xff08;1&#xff09;按运算对象的数目&#xff1a; 单目运算符 双目运算符 三目运算符 &#xff08;2&#xff09;按运算对象的数目&#xff1a; 算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符、自增自减运算符、…