Почему Resources.getString () может периодически возвращать строки из неправильной локали? - PullRequest
26 голосов
/ 11 февраля 2011

У меня есть приложение для Android с английскими строками в values ​​/ strings.xml.Для каждой строки в этом файле у меня есть запись в values-ja / strings.xml с японским переводом этой строки.Если я установлю эмулятор, Nexus One или Nexus S на японский, пользовательский интерфейс будет отображать текст на японском языке.Большую часть времени.

Иногда некоторая часть пользовательского интерфейса отображается на английском языке, хотя текущим языковым стандартом является ja-JP.Например, я написал этот тестовый код в методе onCreate () одного из моих действий:

Log.e(TAG, "Default locale = '" + Locale.getDefault().toString() + "'");
Log.e(TAG, "My string = '" + getResources().getString(R.string.my_string) + "'");

Иногда я вижу в LogCat:

Default locale is 'ja_JP'
My string is '日本'

В других случаях я увижу:

Default locale is 'ja_JP'
My string is 'English'

Иногда эта проблема решается поворотом телефона.Иногда это решается путем выхода и перезапуска приложения.Иногда только часть одного экрана на английском языке.Иногда эта проблема возникает со строками, которые извлекаются из ресурсов через код, а иногда это происходит со строками, на которые ссылается только макет.Нигде в моем приложении я не вызываю Locale.setDefault (), так что это не вызывает проблему.

ОБНОВЛЕНИЕ

Я нашел способ исправить проблему дляконкретная деятельность.В этом действии onCreate ():

Log.e(TAG, "getString: '" + getString(R.string.my_string) + "'");
Log.e(TAG, "getResources().getConfiguration(): '" +
      getResources().getConfiguration().toString() + "'");
Log.e(TAG, "getResources().getDisplayMetrics(): '" +
      getResources().getDisplayMetrics().toString() + "'");

Log.e(TAG, "Setting configuration to getConfiguration()");
getResources().updateConfiguration(getResources().getConfiguration(),
     getResources().getDisplayMetrics());

Log.e(TAG, "getString: '" + getString(R.string.my_string) + "'");
Log.e(TAG, "getResources().getConfiguration(): '" +
      getResources().getConfiguration().toString() + "'");
Log.e(TAG, "getResources().getDisplayMetrics(): '" +
      getResources().getDisplayMetrics().toString() + "'");

Это приводит к следующему в LogCat:

getString: 'English'
getResources().getConfiguration(): '{ scale=1.0 imsi=0/0 loc=ja_JP touch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=8}'
getResources().getDisplayMetrics(): 'DisplayMetrics{density=1.5, width=480, height=800, scaledDensity=1.5, xdpi=254.0, ydpi=254.0}'
Setting configuration to getConfiguration()
getString: '日本'
getResources().getConfiguration(): '{ scale=1.0 imsi=0/0 loc=ja_JP touch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=8}'
getResources().getDisplayMetrics(): 'DisplayMetrics{density=1.5, width=480, height=800, scaledDensity=1.5, xdpi=254.0, ydpi=254.0}'

Как видно из журнала, ничего в текущей конфигурации не меняется, кроме getString() дает разные результаты.

Нецелесообразно использовать этот обходной путь в каждом месте моего приложения, где может использоваться ресурс, но, надеюсь, это дает подсказку о том, что идет не так.

Ответы [ 2 ]

1 голос
/ 23 апреля 2011

Это всего лишь теория, но вы можете просочиться в контекст. По сути, старая операция может сообщать о строковых значениях, а не о вновь созданных в.

Способ проверить это:

  1. Заменить TAG на переменную-член (НЕ STATIC!).
  2. OnCreate, установите TAG = this.toString (), это поместит адрес памяти действия в качестве тега.
  3. Распечатайте упражнение с использованием исходного языка.
  4. Делайте все, чтобы изменить локаль. Это должно (никогда не проверять это) перезапустить действие, и вы получите новое действие. Если вы делаете. Затем посмотрите на журнал и посмотрите, меняется ли адрес памяти для тега. Если адрес памяти такой же, как и прежде, контекст просочился.
0 голосов
/ 14 февраля 2011

Вы меняете локаль во время работы приложения?Если да, правильно ли вы реализовали различные элементы жизненного цикла действия (включая onSaveInstanceState() и onRestoreInstanceState())?

Согласно http://developer.android.com/guide/topics/resources/runtime-changes.html, изменение конфигурации во время выполнения должно привести к тому, что действиебыть уничтожены и перезапущены.Похоже, ваше приложение замечает новую конфигурацию, но не перезагружается должным образом (до перезапуска всего приложения или изменения ориентации).

Вы делаете что-то напуганное в onSaveInstanceState или onDestroy?

Ps Если это исправляет себя только при определенных изменениях ориентации, можете ли вы посоветовать, происходят ли эти изменения ориентации в макетах, которые имеют разные файлы макетов по вертикали и горизонтали?

...