2011-02-11 12 views
24

Mam aplikację dla systemu Android z angielskimi ciągami znaków w wartościach/strings.xml. Dla każdego ciągu w tym pliku mam wpis w wartościach-ja/strings.xml z japońskim tłumaczeniem tego ciągu. Jeśli ustawię emulator, Nexus One lub Nexus S na japoński, interfejs użytkownika będzie wyświetlał tekst w języku japońskim. Większość czasu.Dlaczego Resources.getString() może sporadycznie zwracać ciągi znaków z niewłaściwych ustawień narodowych?

Czasami część interfejsu jest wyświetlana w języku angielskim, mimo że bieżącym ustawieniem jest ja-JP. Na przykład, napisałem ten kod testowy w metodzie onCreate() z jednym z moich działań:

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

Czasem widzę w LogCat:

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

innym razem widzę:

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

Niekiedy ten problem można rozwiązać obracając telefon. Czasami jest to rozwiązywane przez zamknięcie i ponowne uruchomienie aplikacji. Czasami tylko część pojedynczego ekranu jest w języku angielskim. Czasami ten problem występuje z ciągami, które są wyciągane z zasobów za pośrednictwem kodu, a czasami występuje z ciągami, do których odwołuje się tylko układ. Nigdzie w mojej aplikacji nie nazywam Locale.setDefault(), więc to nie powoduje problemu.

UPDATE

Znalazłem sposób, aby skorygować ten problem dla określonej aktywności. W tej działalności za 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() + "'"); 

Powoduje to następujące w 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}' 

Jak widać z dziennika, nic w obecnych zmian w konfiguracji, ale getString() daje inny wyniki.

Używanie tego obejścia w każdym miejscu w mojej aplikacji, w którym można użyć zasobu, jest niepraktyczne, ale mam nadzieję, że stanowi to wskazówkę co do tego, co dzieje się nie tak.

+0

Czy wypróbowałeś google tropiciela błędów Androida? http://code.google.com/p/android/issues/ –

+0

jakiej wersji AVD używasz? – rockeye

+0

Przeanalizowałem każdą wadę modułu do śledzenia błędów, który zawiera "język" lub "locale". Nie widziałem nikogo innego zgłaszającego ten problem. –

Odpowiedz

0

Czy zmieniasz ustawienia regionalne podczas działania aplikacji? Jeśli tak, czy prawidłowo wdrożyłeś różne elementy cyklu życia działania (w tym onSaveInstanceState() i onRestoreInstanceState())?

Zgodnie z http://developer.android.com/guide/topics/resources/runtime-changes.html zmiana konfiguracji w środowisku wykonawczym powinna spowodować, że działanie zostanie ponownie uruchomione. & zostanie ponownie uruchomiony. Wygląda na to, że Twoja aplikacja dostrzega nową konfigurację, ale nie uruchamia się poprawnie (aż do ponownego uruchomienia całej aplikacji lub zmiany orientacji).

Czy robisz coś ciekawego w onSaveInstanceState lub onDestroy?

P.s. Jeśli poprawi się tylko w przypadku pewnych zmian orientacji, czy możesz doradzić, czy te zmiany orientacji występują w układach, które mają różne pionowe pliki układu poziomego &?

+0

Byłem także zaniepokojony cyklem życia aktywności. Umieszczam instrukcje Log.e() na każdym onCreate() i onDestroy(). Po zmianie języka w ustawieniach system operacyjny automatycznie niszczy i ponownie tworzy działania. Żadna z naszych implementacji onSaveInstanceState() nie robi nic poza tym, który zapisuje lokalny plik dziennika. –

+0

Mówiąc o cyklu życia, aplikacja zawiera zarówno kod natywny, jak i usługę w tle. Nie sądzę jednak, żeby te wpłynęły na zasoby. –

+0

Aplikacja nie deklaruje żadnych klauzul android: configChanges w AndroidManifest.xml, więc obsługa zmian konfiguracji jest automatyczna. Aplikacja nie ma różnych plików układu dla różnych orientacji. –

1

To tylko teoria, ale you could be leaking a Context. Zasadniczo stara aktywność może zgłaszać wartości łańcuchowe, a nie nowo utworzone.

sposób na sprawdzenie tego jest: (! Nie statyczne)

  1. Zmień TAG do zmiennej członka.
  2. OnCreate, ustaw TAG = this.toString(), to wstawi adres pamięci aktywności jako tag.
  3. Wydrukuj rzeczy za pomocą początkowych ustawień narodowych.
  4. Zrobić wszystko, aby zmienić ustawienia regionalne. To powinno (nigdy tego nie zweryfikować) ponownie uruchomić działanie, a otrzymasz nową aktywność. Jeśli zrobisz. Spójrz na dziennik i zobacz, czy adres pamięci zmienia się dla tagu. Jeśli adres pamięci jest taki sam jak przed wyciekiem kontekstu.
+0

Próbowałem nieco innej metody: umieściłem punkt przerwania w wywołaniu getString(), które jest w metodzie onCreate() działania. Patrzę na wartość tego, która jest Aktywnością (która jest także kontekstem). Za każdym razem jest inaczej. Nie sądzę, że to jest przyczyną problemu. –

Powiązane problemy