Android 资源 ID 突然不是最终的,switch()es 坏了



前言:这个问题已经过时了,它是在首选的Android开发环境是带有Android插件的Eclipse的时候写的。


我有一段时间有一个Java Android项目。今天,我更新了Android开发工具到Google的最新版本。项目中断了,我得到了一堆"大小写表达式必须是常量表达式"编译错误信息。

结果是R.java文件现在以不同的方式生成。以前,它会有一堆

public static final int MyID=0x12340000;

语句;现在,它看起来像这样(在清理/重建之后):

public static int MyID=0x12340000;

final消失。因此,我拥有的所有资源id开关(我有几个)都是错误的。请问发生了什么事?只有我这样吗?这里的基本原理是什么?有文档记录吗?我能把final带回来吗?

这发生在昨天,当SDK/ADT 14发布时:

从ADT 14开始,库项目中的资源常量不再是决赛。这在http://tools.android.com/tips/non-constant-fields

中有更详细的解释

ADT 14有一个快速修复:http://tools.android.com/recent/switchstatementconversion

引用基本原理:

当组合多个库项目时,字段(必须是唯一的)可能发生冲突。adt14之前,所有字段是最终的,因此,所有库都必须拥有它们的所有资源和相关的Java代码与主程序一起重新编译项目。这对性能不利,因为这使得构建非常缓慢。它还阻止了分发库不包括源代码的项目,限制了使用范围图书馆项目。

字段不再是final的原因是,这意味着库jar可以编译一次,并直接在其他项目中重用。除了允许分发二进制版本的库项目(将在r15中出现),这使得构建速度更快。

请添加括号:

switch (view.getId()) {
    case (R.id.view1):
        break;
    case (R.id.view2):
        break;
}

你可以切换到使用If/Else语句,这样警告就会消失。

示例:

    @Override
    public void onClick(final View v) {
        //finds which button was pressed
        final int buttonView = v.getId();
        String current = fromEditText.getText().toString();
        if (buttonView == R.id.bA) {
            current += getString(R.string.a);
        } 
  }

Google建议您使用if/else条件

http://tools.android.com/tips/non-constant-fields

要自动更改它们,您可以将插入符号放在switch关键字上并按Alt + 在Windows上输入 (Option + Enter在Mac上)并选择将'switch'替换为'if'

你应该使用视图绑定!

android {
    ...
    viewBinding {
        enabled = true
    }
}

这是因为在新的AGP版本中,Google使所有资源id非final,在项目根目录下的gradle.properties文件中添加android.nonFinalResIds=false,以确保AGP生成最终res将使您避免修改代码。

只需将此片段添加到模块级build.gradle文件中:

android {
    ...
    lintOptions {
        disable 'NonConstantResourceId'
    }
}

:https://developer.android.com/studio/write/lint gradle

最新更新