Skip to content

Android.R 需要常量表达式

这个问题一般出现在使用较新版本 Android Gradle Plugin (AGP) 的项目中,主要体现在 switch 语句中使用 R.id.xxx 时出现编译错误。

问题描述

*.java:XXX: 错误: 需要常量表达式
case R.id.xxx:
````

## 问题分析

从 AGP 8.0 起,`R.id.*` 默认不再是 `final` 编译时常量,而是在运行时生成的。这一改动旨在提升增量编译性能,但也带来了副作用:

* `switch-case` 语句要求 `case` 标签是编译期常量;
* 因此不能再直接使用 `R.id.xxx` 作为 `case` 条件。

详见 [官方说明][1]。

## 解决方案

### 方法一:使用 `if-else` 替代 `switch`(推荐)

```java
int id = view.getId();

if (id == R.id.button1) {
    // 处理 button1
} else if (id == R.id.button2) {
    // 处理 button2
}

💡 在 Android Studio 中,可以使用快捷键 Alt+Enter 快速将 switch-case 转换为 if-else

方法二:降级使用旧版本 AGP(不推荐)

如果确实需要 switch-case 语法,可将 build.gradle 中的 AGP 降级至 7.x 或以下。但此方式会导致失去新版本功能与安全更新,不推荐

方法三:使用第三方工具生成 final ID(不推荐)

如 ButterKnife 提供的 R2.id.xxxfinal 的,但该方案已过时且兼容性差,不建议使用。

总结

为适应 AGP 的变更,应避免在 switch-case 中使用 R.id.xxx,推荐使用 if-else 语句以保证代码兼容性与可维护性。

Ref