【Android】使用productFlavors构建多个变体

项目需求

在一个设备上安装两个一样的程序app

需求解决

我们知道每一个app都有一个包名的,如果一个app在Android设备上安装之后,再安装这个app的话会进行覆盖安装,因为他们两个的包名是一样的,默认是一个app。

但是我们现在需要将这一个app多次安装在一个Android设备上,那需要怎么实现这个需求呢?

实现这个需求的话,需要修改包名,我们可以使用productFlavors进行变体的构建和打包,这样的话,我们就可以将同一个app打包成不同包名的apk文件,这样就可以在一个Android设备上进行多次安装了。


Product Flavors允许开发者创建不同的应用版本,每个版本可以有不同的应用ID、版本名称、资源等。常见的用法包括:

  • 免费版与付费版
  • 不同功能集
  • 地区版本

每个变体都可以有不同的配置,包括代码、资源和依赖项。

例如在这个项目里面
我们可以构建两个资源文件目录
在这里插入图片描述
在和【res】同级别的目录下创建【res-flavors】文件夹,在这个文件下面创建两个文件夹【compass】和【wireless】两个资源文件夹,在里面放我们需要区别的文字、图片等资源,但是要注意,资源对应的名字是要相同的,资源可以不同。

接下来我们去【build.gradle】文件里面去构建我们的变体。

android {compileSdkVersion 24buildToolsVersion "24.0.1"defaultConfig {applicationId "com.example" //原包名minSdkVersion 19targetSdkVersion 24versionCode 1versionName "v" + releaseTime()}compileOptions {encoding 'GBK'}lintOptions {abortOnError false}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}applicationVariants.all { variant ->variant.outputs.all { output ->def flavorName = variant.flavorNameif (flavorName == "compass") {outputFileName = "xx校正仪.apk" // 为 compass flavor 设置文件名} else if (flavorName == "wireless") {outputFileName = "xxxxxxxx校验仪.apk" // 为 wireless flavor 设置文件名} else {outputFileName = "xx校正.apk"}}}flavorDimensions "default"productFlavors {compass {applicationId "com.ble.compass"versionName "version compass 1.0"}wireless {applicationId "com.ble.wireless"versionName "version wireless 1.0"}}sourceSets {compass.res.srcDirs = ['src/main/res-flavors/compass']wireless.res.srcDirs = ['src/main/res-flavors/wireless']}}static def releaseTime() {return new Date().format("yyyMMdd_HHmm", TimeZone.getTimeZone("GMT+08:00"));
}

在这里面

   sourceSets {compass.res.srcDirs = ['src/main/res-flavors/compass']wireless.res.srcDirs = ['src/main/res-flavors/wireless']}

是资源文件目录,指向的位置就是我们之前创建的文件地址。

    productFlavors {compass {applicationId "com.ble.compass"versionName "version compass 1.0"}wireless {applicationId "com.ble.wireless"versionName "version wireless 1.0"}}

这两个就是我们创建的两个变体,里面设置了相应的变体的包名和版本名字。

    applicationVariants.all { variant ->variant.outputs.all { output ->def flavorName = variant.flavorNameif (flavorName == "compass") {outputFileName = "xx校正仪.apk" // 为 compass flavor 设置文件名} else if (flavorName == "wireless") {outputFileName = "xxxxxxxx校验仪.apk" // 为 wireless flavor 设置文件名} else {outputFileName = "xx校正.apk"}}}

这一部分就是在输出我们构建好的apk文件的名字,这样我们在进行构建apk文件之后,就会根据相应的变体显示相应的名字。

在这里插入图片描述

通过这样设置之后,【build】构建一下,然后我们在进行apk文件打包的时候就可以选择相应的版本了。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

AI笔筒操作说明及应用场景

AI笔筒由来: 在快节奏的现代办公环境中,我们一直在寻找既能提升效率、增添便利,又能融入企业文化、展现个人品味的桌面伙伴。为此,我们特推出专为追求卓越、注重细节的您设计的AI笔筒礼品版,它集高科技与实用性于一身…

【笔面试常见题:三门问题】用条件概率、全概率和贝叶斯推导

1. 问题介绍 三门问题,又叫蒙提霍尔问题(Monty Hall problem),以下是蒙提霍尔问题的一个著名的叙述,来自Craig F. Whitaker于1990年寄给《展示杂志》(Parade Magazine)玛丽莲沃斯莎凡特&#x…

Elasticsearch中时间字段格式用法详解

Elasticsearch中时间字段格式用法详解 攻城狮Jozz关注IP属地: 北京 2024.03.18 16:27:51字数 758阅读 2,571 Elasticsearch(简称ES)是一个基于Lucene构建的开源、分布式、RESTful搜索引擎。它提供了全文搜索、结构化搜索以及分析等功能,广泛…

sql数据库-DQL-基本查询

目录 举例表emp 查询多个字段 查询整张表所有数据 给字段名起别名(更方便阅读) 去除重复的数据 举例表emp 查询多个字段 SELECT 字段1,字段2,字段3...FROM 表名; 举例查询emp表中的name,workno,age字段返回 查询整张表所有数据 …

JqGird 动态生成列使用

使用场景: 在工作用需要自定义动态生成列,通过选择下拉框,加载列,通过查询加载列对应的数据信息 当选择文件源任务显示三列 当选择数据源任务显示两列 处理方式: 1. 首先在刚进入界面时初始化控件 $("#pageGri…

Rust项目结构

文章目录 一、module模块1.二进制文件的cargo项目2.库的cargo项目3.文件内的module 二、模块化项目结构1.关于module2.各个模块之间互相引用 三、推荐项目结构1.实例 参考 一、module模块 crate规则: 规则一:一个包中必须至少包含一个crate规则二&#…

电能管理系统(源码+文档+部署+讲解)

本文将深入解析“电能管理系统”的项目,探究其架构、功能以及技术栈,并分享获取完整源码的途径。 系统概述 “工厂电能管理系统” 是一款集设备管理、维修管理、能耗监测、节能分析、储能管理、充电桩管理、冷源站管理、报警管理、点检管理等功能于一体…

网上纪念馆(源码+文档+部署+讲解)

最近我在挖掘一些优秀的开源项目时,无意间发现了一个相当给力的系统——网上纪念馆系统。这个系统不仅功能完善,满足了线上祭祀和纪念的需求,而且代码结构清晰,易于二次开发。作为一名技术爱好者,我觉得有必要把这个好…

华为HarmonyOS打造开放、合规的广告生态 - 贴片广告

场景介绍 贴片广告是一种在视频播放前、视频播放中或视频播放结束后插入的视频或图片广告。 接口说明 接口名 描述 loadAd(adParam: AdRequestParams, adOptions: AdOptions, listener: AdLoadListener): void 请求单广告位广告,通过AdRequestParams、AdOptions…

责任链模式 Chain of Responsibility

1 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 2 结构 Handler 定义一个处理请求的接口;(可选)实现后继链。 ConcreteHandler …

【Linux】- 权限(2)

接上一篇文章,继续介绍linux权限的相关知识。https://blog.csdn.net/hffh123/article/details/143432940?spm1001.2014.3001.5501j 目录 一、chown:修改文件的拥有者 二、chgrp:修改文件所属组 三、关于other的介绍 四、文件类型 1、分类…

RTX5/FreeRTOS全家桶源码工程综合实战模板集成CANopen组件(2024-10-30)

【前言】 之前的视频教程分享了两期CANopen的专题,配套的例子都是基于裸机的,为了方便大家在OS下使用,本期视频带OS下的支持。 CANopen协议栈专题,实战方式系统了解NMT,PDO,SDO,时间戳&#x…

vue中实现列表无缝动态滚动

要想实现列表的动态无缝滚动,这里推荐两款组件,vue-seamless-scroll和vue3-seamless-scroll,组件的用法也非常简单,以下是使用方式。 vue2 vue2版本使用vue-seamless-scroll vue-seamless-scroll文档https://chenxuan0000.gith…

BeanDefinition体系架构(待...)

AbstractBeanDefinition 仅仅只有三个直接的子类,分别是:RootBeanDefinition、ChildBeanDefinition、GenericBeanDefinition 注:在 Spring2.5 之前,仅仅只有 RootBeanDefinition、ChildBeanDefinition 两个子类, 我们…

002-Kotlin界面开发之Kotlin旋风之旅

Kotlin旋风之旅 Compose Desktop中哪些Kotlin知识是必须的? 在学习Compose Desktop中,以下Kotlin知识是必须的: 基础语法:包括变量声明、数据类型、条件语句、循环等。面向对象编程:类与对象、继承、接口、抽象类等。…

基于SpringBoot的教务系统

本系统集成了权限管理与用户管理两大核心功能,允许灵活添加用户角色及其对应权限。 技术选型:SpringBootVueShiromybatis 当前系统预设了四种用户类型,具体如下: 管理员:拥有系统的全部权限,涵盖基础管理…

详解Python面向对象程序设计

Python面向对象程序设计 1,初识类和对象2,类的定义和使用3,构造方法4,常用的类内置方法4.1,字符串方法:__str__ 4.2,是否小于:__lt__4.3,是否小于等于:__le__…

LeetCode 热题100之二分

关于二分,之前也写过一篇,参考二分Acwing 1.搜索插入位置 思路分析:典型的 二分查找算法,用于在一个已排序的数组中查找目标值的位置。如果找到了目标值,返回其索引;如果没有找到,则返回目标值…

Python+Appium+Pytest+Allure自动化测试框架-安装篇

文章目录 安装安装ADT安装NodeJs安装python安装appium安装Appium Server(可选)安装Appium-Inspector(可选)安装allure安装pytest PythonAppiumPytestAllure框架的安装 Appium是一个开源工具,是跨平台的,用于…

Twitter(X)2024最新注册教程

Twitter 现名为X,因为图标是一只小鸟的形象,大家也叫它小蓝鸟(埃隆马斯克于 2023 年对该平台进行了品牌重塑),目前仍然是全球最受欢迎的社交媒体和微博平台之一,全球活跃用户量大概在4.5亿。尤其是欧美国家…