根据 buildType 使用 gradle 覆盖资源

2024-01-10

我想用 gradle 覆盖 res/strings.xml 中的一些字符串。

我知道自 Android Gradle 插件 0.7.+ 起 http://tools.android.com/tech-docs/new-build-system可能有一个特定于变体的源文件夹。 但我的应用程序有很多风格,我不想添加额外的变体特定文件夹。

更新2014-01-17

我想要的详细内容:

我的资源中有一些变量仅取决于构建类型(例如“release”)。 首先我以为我的解决方案_1(资源合并后覆盖数据)很好,因为如果我必须更改这些变量,我只需在 build.config 中更改它们(仅一处)。 但正如斯科特·巴塔(Scott Barta)在下面的评论中所写的那样,有一些充分的理由可以解释为什么这个解决方案不是一个好主意。

所以我尝试了另一种解决方案解决方案_2(只需合并正确的资源)基于shakalaca 的 GitHub 项目 https://github.com/shakalaca/learning_gradle_android/blob/082fa1575de1fa75ef09c90cb0cfdd60407e184d/07_tricks/app/build.gradle。我认为这种方式更优雅,而且我仍然有优势,只需更改中的变量one place!

SOLUTION_1(资源合并后覆盖数据):

我在 AS 0.4.2 中做了什么:

  • in build.gradle我尝试将字符串“Hello World”覆盖为“OVERRIDE”(根据我在这篇文章中的回答 https://stackoverflow.com/questions/17465353/how-to-replace-a-string-for-a-buildvariant-with-gradle-in-android-studio):

    android.applicationVariants.all{ variant ->
        // override data in resource after merge task
        variant.processResources.doLast {
            overrideDataInResources(variant)
        }
    }
    
    def overrideDataInResources(buildVariant){
        copy {
            // *** SET COPY PATHS ***
            try {
                from("${buildDir}/res/all/${buildVariant.dirName}") {
                    // println "... FROM: ${buildDir}/res/all/${buildVariant.dirName}"
                    include "values/values.xml"
                }
            } catch (e) {
                println "... EXCEPTION: " + e
            }
    
            into("${buildDir}/res/all/${buildVariant.dirName}/values")
            // println "... INTO: ${buildDir}/res/all/${buildVariant.dirName}/values"
    
            // --- override string "hello_world"
            filter {
                String line ->
                    line.replaceAll("<string name=\"hello_world\">Hello world!</string>",
                            "<string name=\"hello_world\">OVERRIDE</string>");
            }
    
        // *** SET PATH TO NEW RES *** 
        buildVariant.processResources.resDir = file("${buildDir}/res/all/${buildVariant.dirName}/values/values/values.xml")
        // println "... NEW RES PATH: " + "${buildDir}/res/all/${buildVariant.dirName}/values/values/values.xml"
        }
    }
    

复制和过滤任务工作正常,但我无法将“新”values.xml 设置为字符串资源。

SOLUTION_2(只需合并正确的资源)

  • 为特定的构建类型定义风格(例如“releaseRes”)
  • 将此资源与您想要构建的风味合并:

    android.applicationVariants.all{ variant ->
        variant.mergeResources.doFirst{
            checkResourceFolder(variant)
        }
    }
    
    def checkResourceFolder(variant){
        def name = variant.name;
        if(name.contains("Release")){
           android.sourceSets.release.res.srcDirs = ['src/releaseRes/res']
           android.sourceSets.flavor1.res.srcDirs = ['src/flavor1/res']
        }
    }
    

您应该努力提出一个不涉及在构建文件中编写任何自定义代码的解决方案,尤其是那些通过动态重新分配源集来完成棘手事情的代码。自定义 Gradle 代码编写起来有点时髦,并且难以调试和维护。新的构建系统非常强大,并且已经具有大量的灵活性,并且您很可能已经可以做您想做的事情;这只是学习方法的问题。

特别是如果您刚刚学习 Android-Gradle 项目的来龙去脉(而且它对我们来说都是新事物),最好在跳出框框思考之前努力尝试使用系统内置的功能。

一些建议:

  • 您不太可能需要根据构建类型改变资源。 Android-Gradle 中的构建类型应该类似于调试或发布,其区别在于可调试性、编译器优化或签名;构建类型应该在功能上彼此等效。如果你看一下您可以通过 Groovy DSL 在构建类型上设置属性 http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Types,你可以看到意图:debuggable, jniDebugBuild, renderscriptDebugBuild, renderscriptOptimLevel, packageNameSuffix, versionNameSuffix, signingConfig, zipAlign, runProguard, proguardFile, proguardFiles.
  • 如果您仍然认为想要根据构建类型改变资源,那么使用当前的构建系统已经有一种简单的方法可以做到这一点。您可以拥有一个特定于构建类型的资源目录,将资源放在那里,构建系统中的资源合并将在构建时为您处理好事情。这是 Android/Gradle 中强大的功能之一。看使用构建风格 - 正确构建源文件夹和 build.gradle https://stackoverflow.com/questions/16737006/using-build-flavors-structuring-source-folders-and-build-gradle-correctly有关如何使其发挥作用的信息。
  • 如果您想根据构建类型更改某些内容,并且您的需求非常快速且简单,那么您可能希望在 Java 代码中而不是资源中或在构建系统中进行切换。有的是BuildConfig这类事情的机制——它是一个 Java 类,它定义了一个DEBUG基于调试/发布构建状态进行标记,并且您可以添加来自不同构建类型的自定义 Java 代码来执行更有意义的操作。BuildConfig旨在允许构建类型之间存在较小的功能差异,适用于调试构建可能想要执行一些浪费的操作来协助开发的情况,例如进行更广泛的数据验证或创建更详细的调试日志记录,而这些浪费的事情最好被优化掉发布版本。话虽如此,这可能是一种适合您想做的事情的机制。
  • 考虑对您目前使用的构建类型使用风格。从概念上讲,风格有点像构建类型,因为它是可以构建的应用程序的另一种变体;构建系统将创建口味与构建类型的矩阵,并且可以构建所有组合。然而,风格针对不同的用例,其中不同的风格共享大部分代码,但可能具有显着的功能差异。一个常见的例子是应用程序的免费版本与付费版本。由于应用程序不同变体中的不同资源代表不同的功能,这可能表明需要不同的风格。风味可以有不同的资源目录,这些目录在构建时以与构建配置相同的方式合并;请参阅上面链接的问题以获取更多信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据 buildType 使用 gradle 覆盖资源 的相关文章

随机推荐

  • HTML 输入数字步骤无需验证

    在 HTML 中 您可以添加step属性为数字类型的输入 我想要这个是因为我喜欢它如何通过仅按向上 向下键来简化用户的输入 我发现此属性的另一个功能是 它强制用户停留在该间隔内 HTML 通过验证来实现这一点 您可以手动输入任何值 但它不会
  • jQuery 选择器中的通配符

    我正在尝试使用通配符来获取 id 以 jander 开头的所有元素的 id 我试过 jander jander 但它不起作用 我知道我可以使用元素的类来解决它 但也可以使用通配符 div div div div 要获取所有以 jander
  • achartengine x 轴标签与值相比发生偏移

    我注意到我的时间表的 Xlabel 与 X 不同步 价值观 这些点应该位于标签的正上方 在左侧 可以 但是它向右移动 我不知道如何解决这个问题 我得到什么 http tinypic com r 2uqj905 7 http tinypic
  • Mysql:不允许从函数返回结果集

    我写了一个函数但收到此错误不允许从函数返回结果集 DELIMITER CREATE FUNCTION getTestFunction p ParentID int p ListName nvarchar 50 p Type nvarchar
  • matlab中识别相邻像素

    我们假设 A 是 1 1 1 1 1 1 1 2 2 3 3 3 4 4 2 2 3 3 4 4 2 2 2 3 4 4 4 4 3 3 5 5 5 5 5 5 我需要识别与特定强度值相邻的所有数字 例如 强度 1 3 和 4 与强度值 2
  • 从自定义路径预加载 env 文件

    我试图在节点应用程序启动时预加载 env 文件 我有以下配置 但每当我运行时npm run start dev我收到错误 scripts lint tslint project tsconfig json build tsc prestar
  • 如何调整 Altair 中的比例范围?

    当使用 Altair 绘制一组图时 我无法将所有轴调整到相同的比例 如下所示 class list c CS m c CS s c SC m c SC s t CS m t CS s t SC m t SC s list of plots
  • 限制 ruby​​ 文件流的速率

    我正在开发一个项目 该项目涉及将 Flash 视频文件从多个地理分布的节点上传到 S3 存储桶 每个视频文件约为 2 3mb 我们每十分钟仅发送一个文件 每个节点 但是我们消耗的带宽需要将速率限制在 20k s 因为这些节点将流媒体传输到C
  • linux 查找正则表达式

    我在使用正则表达式时遇到问题find命令 可能我不明白如何在命令行上转义 为什么这些不一样 find regex 1234567890 find regex digit bash Ubuntu 你应该看看 regextype的论证find
  • 如何使第一个网格项目跨度为 100%?

    我有以下桌面版 它创建了 4 个相等的列 全部为 25 footer inner display grid grid template columns repeat 4 1fr div class footer inner div One
  • 正则表达式检测双花括号之间的文本

    使用正则表达式 我想检测开始和结束双大括号之间的文本 字符串 并且它应该检测任何内部大括号以及文本 例如 detect this and this as well text but text does not ends here so it
  • 设置背景颜色或 WPF (4.0) 列表框 - Windows 8

    我试图将选定的 ListBoxItem 的背景颜色设置为白色而不是系统颜色 我已经阅读了我可以在此处找到的内容 并遵循或相信遵循了那里的建议 更改选定列表框项目的背景颜色 https stackoverflow com questions
  • InvalidArgumentException 请提供有效的缓存路径错误 laravel 5.2

    我正在与Laravel 5 2我运行时出错composer update or artisan optimize 我在我的供应商上搜索过 没有找到compile php 文件 我尝试生成这个我运行工匠优化 我有同样的错误 InvalidAr
  • Visual Studio 从哪里复制 .vs 文件夹中的 applicationhost.config 文件?

    Visual Studio 在 Web 项目的解决方案根目录中创建一个名为 vs 的隐藏文件夹 里面有一个 config 子文件夹 其中包含应用程序主机配置文件 如果 vs 文件夹丢失 Visual Studio 将在我打开解决方案或启动调
  • Android 应用程序在 Reliance JIO 4G 连接中运行不频繁

    我有一个 Android 应用程序 在除 Reliance Jio 之外的所有运营商的 WiFi 和 3G 连接中都可以正常工作 但是 我发现 有时 当使用 Reliance JIO 4G 连接时 Android 应用程序无法连接到我的 H
  • 错误:Google id_token 不允许与此应用程序一起使用。 Firebase 访问在工作后失败

    我正在使用 Google SignIn 然后使用 Firebase 进行身份验证signInWithCredential 传递 Google 凭据 我遵循了所有程序 一切正常 突然它停止工作了 我转到以前的工作代码 但它仍然失败 所以看来数
  • 负填充的影响

    我刚刚开始学习 android 我有一个关于负填充的问题 负内边距究竟如何影响视图 另外 假设我介绍一个bottomPadding 5dp 这是否将 padding 的边界扩展了 5dp 感谢所有帮助 In LinearLayout and
  • 如何在 PHP 中 $_POST 动态分配值? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我在 mySQL 中创建了一个表 其中包含 名称 等字段 并根据该表中的行数动态创建了几个 div 包含表单和按钮 它看起来像这样
  • MemoryCache 不遵守配置中的内存限制

    我正在使用 NET 4 0内存缓存 http msdn microsoft com en us library system runtime caching memorycache v vs 110 aspx应用程序中的类并尝试限制最大缓存
  • 根据 buildType 使用 gradle 覆盖资源

    我想用 gradle 覆盖 res strings xml 中的一些字符串 我知道自 Android Gradle 插件 0 7 起 http tools android com tech docs new build system可能有一