Android 通过productFlavors实现多渠道打包方法示例
作者:ChenYhong 发布时间:2022-08-27 16:04:35
在日常开发中,可能会遇到同一份代码,需要根据运营需求打出不同包名、不同图标、不同名称的Apk,发布到不同的渠道中。Android Studio提供了便捷的多渠道打包实现方法productFlavors
。
本文介绍一下使用productFlavors
来实现多渠道打包。
创建productFlavors
添加Dimension
在app包下的build.gradle中的android闭包下,添加flavorDimension
,代码如下:
android {
...
// 方式1
getFlavorDimensionList().add('example_value')
// 方式2
flavorDimensions "example_value"
}
两种方式选择一种即可,方式1有代码补全提示,方式2没有。
创建productFlavor
在app包下的build.gradle中的android闭包下,创建productFlavors
,代码如下:
android {
...
productFlavors {
// 原始渠道
origin{
// 这里的值与前面flavorDimensions设置的值保持一致
dimension 'example_value'
}
// 示例渠道
exampleFlavor {
// 这里的值与前面flavorDimensions设置的值保持一致
dimension 'example_value'
}
}
}
网上找到的相关文章都说productFlavor
中需要配置dimension
,但是在尝试的过程中发现,如果只添加了一个flavorDimensions
,那么productFlavor
中的dimension
可以不用特别声明(我的gradle版本为7.6,AGP为7.4.1)。
构建完后可以在Build Variants中看到已配置的变体,如图:
渠道包参数配置
打渠道包时,根据需求可能会需要配置不同参数,例如App的名称、图标、版本信息,服务器地址等。
配置不同的签名信息
如果需要使用不同的签名文件,可以在app包下的build.gradle中的android闭包下配置signingConfigs
,代码如下:
android {
signingConfigs {
origin {
keyAlias 'expampledemo'
keyPassword '123456'
storeFile file('ExampleDemo')
storePassword '123456'
}
exampleFlavor {
keyAlias 'exampledemoflavor'
keyPassword '123456'
storeFile file('ExampleDemoFlavor.jks')
storePassword '123456'
}
}
flavorDimensions "example_value"
productFlavors {
origin{
signingConfig signingConfigs.origin
}
exampleFlavor {
signingConfig signingConfigs.exampleFlavor
}
}
}
需要注意的是signingConfigs
必须在productFlavors
前面声明,否则构建会失败。
配置包名、版本号
在productFlavors
中可以配置渠道包的包名、版本信息,代码如下:
android {
...
defaultConfig {
applicationId "com.chenyihong.exampledemo"
versionCode 1
versionName "1.0"
...
}
productFlavors {
origin{
...
}
exampleFlavor {
applicationId "com.chenyihong.exampledflavordemo"
versionCode 2
versionName "1.0.2-flavor"
}
}
}
origin渠道表示的是原始包,不进行额外配置,使用的就是defaultConfig中声明的包名以及版本号。
效果如图:
origin
exampleFlavor
配置BuildConfig,字符串资源
在productFlavors
中配置BuildConfig或者resValue,可以让同名字段,在打不同的渠道包时有不同的值,代码如下:
android {
...
productFlavors {
origin{
buildConfigField("String", "example_value", "\"origin server address\"")
resValue("string", "example_value", "origin tips")
}
exampleFlavor {
buildConfigField("String", "example_value", "\"flavor server address\"")
resValue("string", "example_value", "flavor tips")
}
}
}
配置完后重新构建一下项目,就可以通过BuildConfig.example_value
以及getString(R.string.example_value)
来使用配置的字段。
效果如图:
origin
exampleFlavor
配置manifestPlaceholders
有些三方SDK,会在Manifest中配置meta-data
,并且这些值跟包名大概率是绑定的,因此不同渠道包需要替换不同的值,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
...
>
<meta-data
android:name="channel_value"
android:value="${channel_value}"/>
....
</application>
</manifest>
android {
...
productFlavors {
origin{
manifestPlaceholders = [channel_value: "origin channel"]
}
exampleFlavor {
manifestPlaceholders = [channel_value: "flavor channel"]
}
}
}
效果如图:
origin
exampleFlavor
配置不同的依赖
不同渠道包可能会引用不同的三方SDK,配置了productFlavors
后,可以在dependencies
中区分依赖包,代码如下:
dependencies {
// origin 包依赖
originImplementation("com.google.code.gson:gson:2.10.1")
// exampleFlavor包依赖
exampleFlavorImplementation("com.google.android.gms:play-services-auth:20.4.1")
}
示例:
在FlavorExampleActivity
中同时导入Gson包和Google登录包,效果如下:
origin
exampleFlavor
配置不同的资源
在app/src目录下,创建exampleFlavor文件夹,创建与main包下一样的资源文件夹,打渠道包时,相同目录下同名的文件会自动替换,可以通过这种方式来实现替换应用名称和应用图标。
效果如图:
示例Demo
按照惯例,在示例Demo中添加了相关的演示代码。
ExampleDemo github
来源:https://juejin.cn/post/7198806651562229816
猜你喜欢
- 一个简单的实现版本,没有去Hook键鼠等操作,事先录制好操作步骤(将鼠标移动到需要操作的位置,按下热键执行相应动作),点击运行即可。主要还是
- 小伙伴们,最近比较忙,没什么时间写,今天给大家分享的是JAVA如何导出EXCEL表格,因为最近有做这样一个功能,所以分享出来,如有不对之处,
- 需求:将 一个容器List<Bean> 按照一定的字段进行分组,分组过后的值为特定的BEAN 里面的属性例如:假定有这样一个Be
- 单例模式动机有时候只有一个类的实例是很重要的。比如,一个系统应该只有一个窗口管理实例。单例模式是最简单设计模式:类负责实例化自己,确保只有一
- 一、日志1、配置日志级别日志记录器(Logger)的行为是分等级的。如下表所示:分为:OFF、FATAL、ERROR、WARN、INFO、D
- 前段时间做了一个练手的小项目,名叫Book_Bar,用来卖书的,采用的是三层架构,也就是Models,IDAL,DAL,BLL 和 Web
- 类加载子系统classLoader 只负责对字节码文件的加载,至于是否可以运行,还要看执行引擎。加载的类信息存放于方法区的内存空间,除了类信
- 背景在最近的项目中,有一个需求是对一个很大的数据库进行查询,数据量大概在几千万条。但同时对查询速度的要求也比较高。这个数据库之前在没有使用P
- static和@Component遇到的bug今天在编写util的时候,发现不能调用到工具类里面的方法,转眼一看,原来不是工具类里面的方法是
- 在Activity 添加即可getWindow().addFlags(WindowManager.LayoutParams.FLAG_SEC
- Java中,只有8种基本类型不是对象,例如:4种整形类型(byte, short, int,long),2种浮点类型(flout, doub
- 这篇文章主要介绍了Java String的intern用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 问题springboot 集成springcloud时常常由于版本问题而报错,如下:com.sun.jersey.api.client.Cl
- 一、材料准备1、jdk1.8的安装包2、maven安装包3、idea工具二、配置jdk1.8环境变量1.jdk下载jdk下载网址(点击此链接
- 在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的类和这个类的方法可以使用,其他的类都无法访问到这个private
- 一、前言最近在看android fragment与Activity进行数据传递的部分,看到了接口回调的内容,今天来总结一下。二、回调的含义和
- 本文为大家讲解了Struts2框架的入门知识,供大家参考,具体内容如下1、Struts2框架介绍Struts2框架是MVC流程框架,适合分层
- 首先,看一下效果 可能各位在别处看到过类似的东西,我在微信的文章末尾看到有个玩意,感觉有意思,就用代码实现一下。这篇文章主要把握
- 开发过程中,如果使用mybatis做为ORM框架,经常需要打印出完整的sql语句以及执行的结果做为参考。虽然mybatis结合日志框架可以做
- 使用wpf程序常常会出现一个问题,那就是内存占用过高,使用wpf的程序功能越复杂往往用着用着内存就本着90往上去了。一方面wpf本身是一个u