繁体   English   中英

android.content.res.Resources$NotFoundException:字符串资源 ID

[英]android.content.res.Resources$NotFoundException: String resource ID

应用程序抛出异常

android.content.res.Resources$NotFoundException:字符串资源 ID

我的情况并不常见(因为给定的 ID 确实存在)。 我问这个问题是为了自己回答。

请参阅下面我的回答,为什么会发生这种情况以及为什么会发生在我身上。

您可能已经发现当您尝试将某个整数设置为字符串时会发生此错误,例如:在代码中的某处some_variable被声明为int并且您想显示其值,因此您尝试使用setText()将其设置为some_textview方法:

int some_variable = 0;
TextView txtView = (TextView) findViewById(R.id.someTextView);
... some code/calculations etc...
txtView.setText(some_variable); // exception! some_variable is an int value

它也可以是任何返回 int 作为结果的方法返回的结果,例如:

txtView.setText(someString.length());// exception! String.length() returns an int value
txtView.setText(someSet.size());// exception! Set.size() returns an int value

等等。

这些会导致Resources$NotFoundException因为没有具有此类编号 (id) 的String资源。
您很可能知道在每次构建时都会在构建文件夹中创建一个R.java文件。 该文件包含静态变量,其中在 string.xml String声明的每个变量都有自己的唯一id和一些 int 值,这个id在代码中用作 R.string。 身份证 这就是异常的原因 - 系统将尝试查找 R.string。 id字符串对应于给定的值,但在大多数情况下显然失败。 这也是 setText() 接受整数值而 IDE 不警告您的原因。 在某些情况下,您的some_variable可能会偶然具有与 some id相对应的值。 这些都是棘手的情况,因为不会抛出异常,并且您会看到一些意外的文本(实际上对应于 R.string. id )而不是变量值。
此问题的解决方案很简单(如果必须显示some_variable的值):

txtView.setText(String.valueOf(some_variable));

还有一些人试图以相同的方式将int值设置为Toast消息,例如:

int some_variable = 0;
... some code/calculations etc...
Toast.makeText(this, some_variable, Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), someSet.size(), Toast.LENGTH_LONG).show();

修复方法是一样的:

int some_variable = 0;
... some code/calculations etc...
Toast.makeText(this, String.valueOf(some_variable), Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), String.valueOf(some_Set.size()), Toast.LENGTH_LONG).show();

您可能遇到过使用Integer(some_variable).toString()方法的方法。 它不错。 然而,这意味着将应用 1 个额外的操作(将 int 值包装为整数)并且只能使用整数值(或将抛出NumberFormatException )而对于String.valueOf(some_variable)值类型并不重要,它适用于任何值的类型,包括所有原语(float、double、byte、long 等)并且永远不会抛出任何异常。
还有一些其他情况 - 这里描述了罕见的情况,重点是在 IDE 中清理项目。
如果您非常确定您没有以上述方式传递任何整数,而且这种情况发生在已发布的应用程序中,并且在开发时没有发生,则可能是Locale情况。 如果您的应用程序具有Locale依赖String资源,并且当您测试它时,您可能使用您所在地区特定的Locale设备进行了测试,因此未检测到任何问题。 但是(请记住!)在这种情况下,您必须提供位于项目res\\values文件夹中的默认strings.xml ,如果您错过了它,情况就是如此。 假设某个用户,比如说,来自德国(其设备默认Locale为 DE)的用户试图运行这样的应用程序,该应用程序在文件夹values-envalues-it只有strings.xml (但在valuesvalues-it文件夹中都没有strings.xml values-de文件夹)。 在这种情况下,应用程序将首先尝试定位values-de\\strings.xml但失败,然后它将尝试使用默认values\\strings.xml并再次失败,因此它将崩溃抛出Resources$NotFoundException
解决这个问题的方法是,就像我之前提到的,在项目的res\\values文件夹中提供一个默认的strings.xml ,因此对于任何不受支持的语言环境,将使用默认的语言环境(通常是英语)。 另一种方法是在运行时为您的应用程序设置适当的默认语言环境(例如在应用程序扩展类中),如果它在具有不受支持的语言环境的设备上运行,例如(假设您希望默认使用en语言环境):

    Locale locale = getAppLocale(context);
    String localeLang = locale.getLanguage();
    // default locale is EN but available are EN and RU
    if (!localeLang.equalsIgnoreCase("en") && !localeLang.equalsIgnoreCase("ru")) {
        locale = new Locale("en");
    Configuration config = new Configuration();
    config.locale = locale;

    context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
    }

只需使用 String.valueOf(your_value_here) 当您尝试在 textview 中设置 int 数据类型但尝试 String.valueOf() 函数时,通常会发生此错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM