簡體   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