アプリケーションが例外をスローする
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
_ cuzが発生し、そのような番号(id)のString
リソースがありません。
おそらくご存知のとおり、ビルド時にビルドフォルダーに_R.Java
_ファイルが作成されます。このファイルには静的変数が含まれており、string.xml String
で宣言されたものはすべて、独自の固有のidといくつかのint値を持ち、これはidコードでRとして使用します.string .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値を整数にラップする)が適用され、整数値のみを使用できることを意味します(または、NumberFormatException
がスローされます)が、String.valueOf(some_variable)
値型は使用されません。問題は、すべてのプリミティブ(float、double、byte、longなど)を含むすべてのタイプの値に対して機能し、例外をスローすることはありません。
他にもいくつかのケースがあります- まれなケースはここで説明されています そしてポイントはIDEでプロジェクトをクリーンアップすることです。
上記の方法で整数を渡さないと確信している場合、さらにこれはリリースされたアプリで発生し、開発中には発生しなかった場合は、Locale
の場合があります。アプリにLocale
リソースに依存するString
があり、それをテストしたときに、地域固有のLocale
デバイスを使用して実行した可能性があるため、問題は検出されませんでした。ただし、このような場合は、プロジェクトの_strings.xml
_フォルダーにあるデフォルトの_res\values
_を指定する必要があります。これを見逃した場合は、このようになります。たとえば、ドイツのユーザー(デバイスのデフォルトはLocale
がDE)が、フォルダー_strings.xml
_と_values-en
_に_values-it
_しかないアプリを実行しようとしたとします。ただし、values
にも_strings.xml
_フォルダーにも_values-de
_はありません。この場合、アプリは最初に_values-de\strings.xml
_を見つけようとしますが失敗し、次にデフォルトの_values\strings.xml
_を使用しようとし、もう一度失敗するため、_Resources$NotFoundException
_をスローしてクラッシュします。
この問題の修正は、前述のように、プロジェクトの_strings.xml
_フォルダーにデフォルトの_res\values
_を提供することです。これにより、サポートされていないロケールではデフォルトのロケールが使用されます(通常は英語)。 )。もう1つの方法は、アプリがサポートされていないロケールのデバイスで実行される場合(たとえば、アプリケーション拡張クラス)、実行時にアプリに適切なデフォルトロケールを設定することです(デフォルトで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());
}
_