android - 无法从代码中引用生成的资源

标签 android gradle android-resources android-build gradle-kotlin-dsl

我有一个配置模板文件,其中包含要根据当前构建风格(devDebugprodRelease 等)填写的占位符。

我决定创建一个自定义 Gradle 任务并将其注入(inject)到正确运行的构建流程中,并将正确的配置文件创建到主资源文件夹 (main/res/raw) 中。

我的目标是将生成的配置文件输出到构建文件夹的生成资源中,例如$buildDir/generated/res/myconfig/dev/debug/raw/config.json .我可以将输出的路径设置为类似它并创建文件,但是在尝试从代码访问它时我被卡住了。 AS 也无法识别文件夹 myconfig作为资源根(即使明确标记它)。我在这里想念什么?

这是完成工作的 Gradle 任务(它是 Kotlin):

fun configureMyConfiguration(variant: ApplicationVariant) {
    getTasksByName(
        "generate${variant.name.capitalize()}Resources",
        true
    ).onEach { task ->
        task.dependsOn(
            task("${variant.name}ConfigureMyConfiguration") {
                group = "MyApp"
                description = "Configure my configuration"

                doLast {
                    val configRoot = File("$buildDir/generated/myconfig/${variant.flavorName}/${variant.buildType.name}/res")
                    val templateFile = "$rootDir/app/config_template.json"
                    val configFile = File(configRoot, "raw/my_config.json")
                    val config = File(templateFile).readText()
                        .replace("\${foo}", "bar")

                    configFile.ensureParentDirsCreated()
                    configFile.createNewFile()
                    configFile.writeText(config)

                    project.android.sourceSets.getByName(variant.name) {
                        resources.srcDir(configRoot)
                    }
                }
            }
        )
    }
}

配置应用程序变体时调用设置任务的方法:
applicationVariants.all {
    outputs.forEach {
        configureMyConfiguration(this@all)
    }
}

如您所见,文件夹和文件已在 build 文件夹中成功创建:

generated resources

但是,我认为从代码引用不起作用,因为生成的源无法正确识别和组装。

enter image description here

我尝试将生成的文件夹添加到 android 中的源集中。 gradle 文件的 block - 这样文件夹被标记为资源根目录,但从代码中引用仍然无法正常工作。

最佳答案

编辑

所以resValue不适用于原始值,因此工作方式是将文件的路径注册为 res安卓的路径

正如@bearlysophisticated suggested像这样做

    val configRoot = File("$buildDir/generated/myconfig/${variant.flavorName}/${variant.buildType.name}/res")

    // Registering folder as recognized resourced root
    variant.registerGeneratedResFolders(files(configRoot))

在任务循环之外执行它。以前更好。

编辑结束

问题是您创建了文件,但您从未让 Android 框架对其进行索引。这意味着该文件确实存在,但它没有添加到带有资源引用的 R.java 文件中。 Gradle 有这样的可能性:

你可能会做类似的事情resValue "raw", "json_name", file不工作 - 见 编辑 上一节

我不确定这是否适用于原始资源,因为我没有在实际代码中尝试过它 - 但对于字符串和整数,它可以完美地工作。

希望能帮助到你。

关于android - 无法从代码中引用生成的资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60955055/

相关文章:

android - 用于消息(IM)和文件发送的Skype android api

java - 为什么甚至在点击上传按钮 Android Firebase Storage 之前图像就会自动上传?

java - Kotlin noarg 插件 : Constructor only accessible by java reflection

java - 如何在 Visual Studio Code 中刷新/同步 gradle 项目

android - 为什么 BitmapFactory.decodeResource 会缩放我的图像?

java - 在 proguard android 中忽略警告是正确的

java - 为什么我不能在 AppCompatActivity 的函数外部使用 create 方法

android - 无法通过传递使用子模块找到 lib

java - 单击任意位置后,将 fillAfter 设置为 true 的 Android 动画会重置

android - 关于 android.R.drawable 中 'private' 可绘制对象的说明