Android 在代码中使用 Gradle Build 风格,例如 if 案例
Posted
技术标签:
【中文标题】Android 在代码中使用 Gradle Build 风格,例如 if 案例【英文标题】:Android using Gradle Build flavors in the code like an if case 【发布时间】:2014-07-29 22:49:09 【问题描述】:我正在尝试使用构建风格。在我的 build.gradle 中,我定义了 2 种风味,一种是普通风味,一种是管理员风味。
基本上,admin 风格在主 Activity 上有一个额外的按钮。
我知道我可以为不同的风格定义不同的包/类。但是有没有办法根据风格制作一种 if case 来添加/删除一段代码?
基本上,我需要一个 Activity 的两个版本。但我不想要两个完全不同版本的活动并维护它们。
所以在我的活动中我想做的事
=> gradle 检查风味是否为 'admin'
=>如果是,添加这个按钮的代码
这可能吗?或者您是否需要两种不同的身体活动,从而在之后添加功能时同时维护它们。
【问题讨论】:
您可以在活动的 onCreate 上添加一行来执行此操作:检查风味并让按钮不可见(GONE) 那条线会是什么样子?if(!BuildConfig.FLAVOR.equals("admin")) buttonTheOneWeWanaHide.setVisibility(View.GONE);
【参考方案1】:
BuildConfig.FLAVOR
为您提供综合产品风味。
因此,如果您只有一个风味维度:
productFlavors
normal
admin
然后你就可以检查它了:
if (BuildConfig.FLAVOR.equals("admin"))
...
但如果你有多个风味维度:
flavorDimensions "access", "color"
productFlavors
normal
dimension "access"
admin
dimension "access"
red
dimension "color"
blue
dimension "color"
还有BuildConfig.FLAVOR_access
和BuildConfig.FLAVOR_color
字段,所以你应该像这样检查它:
if (BuildConfig.FLAVOR_access.equals("admin"))
...
而BuildConfig.FLAVOR
包含完整的风味名称。例如,adminBlue
。
【讨论】:
注意:flavorDimension
在 Gradle 2.0 中已替换为 dimension
。
@mixel 只是出于好奇,在这个实现中,我们需要将所有逻辑包含在一个构建中。如果需要简单地更改布尔值,任何人都可以反编译 apk 并重建?为什么不提取逻辑并将逻辑放在不同的文件夹中并使用souceSets
来决定要获取哪个文件夹?这样一来,将整个逻辑暴露给世界就没有问题了。
@IHC_Applroid 是的。 OP 说:“我知道我可以为不同的口味定义不同的包/类”,所以我认为他不能将代码放在不同的 sourceSets
中。
@IHC_Applroid 的想法是,如果我需要构建两个单独的活动,并且需要更改某些内容,我需要每次更改两次。这会降低应用程序的可维护性。因此我看起来像这样。虽然我同意你提到的潜在安全风险。但就我个人而言,我愿意承担这个风险。
最好以这种方式编码if ("admin".equals(BuildConfig.FLAVOR))
,以防 BuildConfig 为空【参考方案2】:
为避免条件中出现纯字符串,您可以定义一个布尔属性:
productFlavors
normal
flavorDimension "access"
buildConfigField 'boolean', 'IS_ADMIN', 'false'
admin
flavorDimension "access"
buildConfigField 'boolean', 'IS_ADMIN', 'true'
那么你可以这样使用它:
if (BuildConfig.IS_ADMIN)
...
【讨论】:
写的时候标有line-through,表示弃用。应该使用什么,以及如何使用? 我在 build.gradle 文件中保留了一些这样的字符串,但它并没有告诉我弃用。 @androiddeveloper 见***.com/questions/24119557/…(对已接受答案的第一条评论) @LoungeKatt 所以请改用“维度”。好的。 其余的应该仍然是最新的,但我只使用一个维度。在我的代码中使用BuildConfig.FLAVOR.equals
更容易。【参考方案3】:
您可以为每个风味定义不同的构建配置字段或不同的资源值(如字符串值),例如(根据Google's gradle tips and recipes),例如,
android
...
buildTypes
release
// These values are defined only for the release build, which
// is typically used for full builds and continuous builds.
buildConfigField("String", "BUILD_TIME", "\"$minutesSinceEpoch\"")
resValue("string", "build_time", "$minutesSinceEpoch")
...
debug
// Use static values for incremental builds to ensure that
// resource files and BuildConfig aren't rebuilt with each run.
// If they were dynamic, they would prevent certain benefits of
// Instant Run as well as Gradle UP-TO-DATE checks.
buildConfigField("String", "BUILD_TIME", "\"0\"")
resValue("string", "build_time", "0")
所以在这种情况下,像
productFlavors
normal
dimension "access"
buildConfigField("boolean", "IS_ADMIN", "false")
admin
dimension "access"
buildConfigField("boolean", "IS_ADMIN", "true")
然后像使用它一样
if (BuildConfig.IS_ADMIN)
...
else
...
或者如果只是为不同的风格设置不同的字符串值,可以使用不同的resValues
,然后你甚至不需要if/then
【讨论】:
【参考方案4】:你可以试试这个方法
productFlavors
def app_name = "you app name"
development
versionCode 1
versionName "1.0.1"
buildConfigField 'String', 'varibalename', ""
release
versionCode 1
versionName "1.0.1"
buildConfigField 'String', 'varibalename', ""
if(BuildConfig.varibalename)
【讨论】:
以上是关于Android 在代码中使用 Gradle Build 风格,例如 if 案例的主要内容,如果未能解决你的问题,请参考以下文章
Android Gradle 构建中不使用 libs 文件夹中的 Jar 文件
如何在 Android Studio 项目中将库添加到 Gradle 构建?
Android Gradle 插件自定义 Gradle 任务 ⑤ ( 为自定义 Gradle 任务添加依赖任务 | Gradle 任务依赖执行顺序控制 )
Android Gradle 插件自定义 Gradle 任务 ⑤ ( 为自定义 Gradle 任务添加依赖任务 | Gradle 任务依赖执行顺序控制 )