【问题标题】:Resource IDs will be non final in AGP 7.0资源 ID 在 AGP 7.0 中将不是最终的
【发布时间】:2021-02-18 16:09:28
【问题描述】:

我有一个annotation processing library 在编译时生成RecyclerView 适配器。

我目前正在从头开始重建它,并进行了许多更改和改进,但在测试时,我收到了一条警告:

在 Android Gradle 插件版本 7.0 中,资源 ID 将是非最终的, 避免将它们用作注释属性

这是一个问题,因为这意味着我将无法在注释中使用 R.layout 变量。

我目前使用它将布局文件的整数值与 R 类变量名相关联;这是从资源文件夹中找到布局文件,然后调用 inflate(layoutResId)。

目前,我是这样解决这个问题的

示例

给定一个简单的ViewHolder 注释。

annotation class ViewHolder(val layoutResId: Int)

随用法

@ViewHolder(R.layout.sample)
data class Sample(val text: String) : GencyclerModel

还有 Generated R.layout 类。

public final class R {
    public static final class layout {
        public static final int sample = 567541283;
    }
}

在处理ViewHolder 注释时,处理器将收到integer567541283

在第一个处理周期中,处理器将分析R 类并创建一个表以将integer 映射到布局名称,在本例中为567541283 sample

有了这些信息,我可以遍历布局资源目录并找到名称为sample.xml 的布局文件。 我也可以稍后拨打inflate(R.layout.sample)

该字段在新版本中将是非最终的,因此会引发编译时错误。

注解参数必须是编译时常量。

可能的解决方案

  1. (Butterknife solution) 创建一个重复的 R 类,它将生成 R.layout 变量为 static final,从而删除我的 R 类依赖项。

  2. (AndroidAnnotations solution)。使用字符串而不是 Resources 类。我不太喜欢这个解决方案,因为如果布局被重命名或拼写错误,它会导致问题。

我不确定我对两者的感觉有多开心,但老实说,我没有看到其他解决方法。

如果有人有更好的方法来解决这个问题,我很想听听,如果没有,你更喜欢哪种解决方案?

谢谢

我正在链接我在 GitHub 项目中打开的 issue,以防你想贡献。

【问题讨论】:

    标签: android android-gradle-plugin annotation-processing


    【解决方案1】:

    另一种解决方案是向 GencyclerModel 添加一个方法,该方法返回布局引用并从注释中删除该引用。我想这种方法唯一会造成的问题是您检查编译器中是否存在布局文件的条件。但是使用这种方法,您不会在注释中硬编码布局引用,而是从每个模型内部的方法中获取它们

    【讨论】:

    • 这行不通,因为如果我将值放入模型中,它在编译时将不可用,我需要它在编译时可用才能找到布局文件并在编译阶段解析所有视图,以便生成代码。
    猜你喜欢
    • 2011-12-12
    • 2023-03-15
    • 1970-01-01
    • 2015-07-06
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    相关资源
    最近更新 更多