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

时间:2013-06-30 08:32:21

标签: android string exception resources locale

应用程序抛出异常

  

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

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

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

2 个答案:

答案 0 :(得分:30)

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

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因为没有String资源具有这样的数字(id)。
你最有可能知道在每个构建时都有一个R.java文件在build文件夹中创建。此文件包含静态变量,其中string.xml String中声明的每个都有自己唯一的带有一些int值的 id ,并且您在代码中使用此 id 作为R.字符串。 ID 。这是异常的原因 - 系统将尝试查找与给定值对应的R.string。 id 字符串,但在大多数情况下显然会失败。这也是为什么setText()接受整数值而IDE不警告你的原因。 在某些情况下,您的some_variable偶然会有一个与 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包装为Integer),并且只能使用整数值(或者NumberFormatException将被抛出),而String.valueOf(some_variable)值类型无关紧要,它适用于任何类型的值,包括所有基元(float,double,byte,long等),并且永远不会抛出任何异常    还有一些其他情况 - rare cases are described here,重点是在IDE中清理项目    如果您非常确定您没有以上述方式传递任何整数,而且这种情况发生在已发布的应用中,并且在开发时没有发生,则可能是Locale情况。如果您的应用具有Locale取决于String资源,并且在您进行测试时,您可能会使用您所在地区的Locale设备进行测试,因此未检测到任何问题。但是(请记住!)在这种情况下,您必须提供位于项目strings.xml文件夹中的默认res\values,如果您错过了,则情况确实如此。假设某个用户(比如德国人的设备默认Locale是DE)试图运行这样的应用程序,该应用程序在文件夹strings.xmlvalues-en中只有values-it(但是strings.xmlvalues文件夹中没有values-de。在这种情况下,应用会首先尝试找到values-de\strings.xml但是会​​失败,然后会尝试使用默认values\strings.xml并再次失败,因此会导致Resources$NotFoundException崩溃。 正如我之前提到的,此问题的修复是在项目的strings.xml文件夹中提供默认res\values,因此对于任何不受支持的语言环境,将使用默认语言环境(通常为英语)。另一种方法是在运行时为应用程序设置正确的默认语言环境(例如在Application扩展类中),如果它在具有不受支持的语言环境的设备上运行,例如(假设您默认使用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());
    }

答案 1 :(得分:-1)

只需使用String.valueOf(在此处输入您的值) 当您尝试在文本视图中设置int数据类型但尝试使用String.valueOf()函数时,通常会发生此错误。