Подтвердить что ты не робот

Почему Resource.getString() может прерывать строки из неправильной локали?

У меня есть приложение Android с английскими строками в значениях /strings.xml. Для каждой строки в этом файле у меня есть запись в значениях-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(), поэтому не вызывая проблемы.

UPDATE

Я нашел способ исправить проблему для конкретной деятельности. В этой деятельности 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() дает разные результаты.

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

4b9b3361

Ответ 1

Это просто теория, но вы можете пропустить Контекст. В основном, старая активность может сообщать строковые значения, а не ново создано на.

Способ проверки:

  • Измените TAG на переменную-член (NOT STATIC!).
  • OnCreate, установите TAG = this.toString(), это поместит адрес памяти в качестве тега.
  • Отредактируйте активность, используя исходный язык.
  • Сделайте все, чтобы изменить локаль. Это должно (никогда не проверено) перезапускать активность, и вы получаете новую активность. Если да. Посмотрите на журнал и посмотрите, меняется ли адрес памяти для тега. Если адрес памяти такой же, как до утечки контекста.

Ответ 2

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

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

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

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

Ответ 3

Я столкнулся с той же проблемой.

Для меня я пытался получить строку (в onCreate()) перед импортом языковых настроек из общих настроек (сделано в onResume()).