【问题标题】:Android resource IDs suddenly not final, switch()'es brokenAndroid 资源 ID 突然不是最终的,switch()'es 坏了
【发布时间】:2011-12-12 01:24:29
【问题描述】:

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


我有一段时间有一个 Java Android 项目。今天,我将 Android 开发工具更新到了 Google 的最新版本。项目崩溃了——我收到一堆“case 表达式必须是常量表达式”的编译错误消息。

事实证明,现在生成的 R.java 文件有所不同。以前,它会有一堆

public static final int MyID=0x12340000;

声明;现在,它看起来(在清理/重建之后)是这样的:

public static int MyID=0x12340000;

final 不见了。所以我所有的资源 ID 开关(我有几个)都是错误的。请问怎么了?只有我吗?这里的理由是什么?它在任何地方都有记录吗?我可以以某种方式将final 带回来吗?

【问题讨论】:

    标签: android eclipse compiler-errors


    【解决方案1】:

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

    从 ADT 14 开始,库项目中的资源常量不再是 最终的。这在http://tools.android.com/tips/non-constant-fields中有更详细的解释

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

    引用理由:

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

    这些字段不再是 final 的原因是它意味着库 jar 可以编译一次并直接在其他项目中重用。除了允许分发库项目的二进制版本(在 r15 中提供)之外,这还可以加快构建速度。

    【讨论】:

    • 确实有道理。我知道他们是从哪里来的。一段时间以来,Android 库只是链接源而不是编译库,这一事实一直是我的一个小痛点。另外,感谢 Google 提供了一个神奇的重构器。
    • 这只是 Android 团队愚蠢的设计决定的结果。每当你看到一些带有一堆幻数常量的生成文件时,你应该觉得它很有趣。谢谢,由于完全缺乏远见,谷歌破坏了一堆开发人员的源代码。公共静态整数。好多了?!
    • 这个答案被标记为解决方案 - 但我没有看到它......非常好的讨论,建议,文档链接等......什么是具体的解决方案?我应该在我的代码中更改什么来解决这个问题 - 请简单地说几句话?还是没有解决办法? ——那么请用一个字回答:“不”。 ?
    • @RussiaDroneFlights 您是否阅读了任何链接?他们说如果您需要有条件地使用资源 ID 进行某些操作,请使用 if-else 子句而不是 switch 语句。 Switch 语句将要求 ID 是最终的,而现在已经有九年多了。
    【解决方案2】:

    您可以切换到使用 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);
            } 
    

    【讨论】:

    • ????❤️ 好一个!
    【解决方案3】:

    Google 建议您使用 if/else 条件

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

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

    【讨论】:

      【解决方案4】:

      你应该使用view binding

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

      【讨论】:

      • 不适用于菜单。最初的问题主要是关于菜单 ID。
      • 添加了很多类,也没有真正解决问题,它只是使用另一种方式来识别和处理视图。
      【解决方案5】:

      只需在模块级 build.gradle 文件中添加此片段即可:

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

      更多: https://developer.android.com/studio/write/lint#gradle

      【讨论】:

      • 禁用 lint 选项的任何缺点。
      • 小心,这只是禁用了 Lint 警告,它本身并没有真正解决问题。
      猜你喜欢
      • 1970-01-01
      • 2023-03-15
      • 2016-05-19
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多