Loading java/src/com/android/inputmethod/keyboard/KeyboardSet.java +35 −27 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ import com.android.inputmethod.keyboard.KeyboardSet.Params.ElementParams; import com.android.inputmethod.latin.InputTypeUtils; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.XmlParseUtils; Loading Loading @@ -66,6 +66,7 @@ public class KeyboardSet { public static class KeyboardSetException extends RuntimeException { public final KeyboardId mKeyboardId; public KeyboardSetException(Throwable cause, KeyboardId keyboardId) { super(cause); mKeyboardId = keyboardId; Loading Loading @@ -161,26 +162,29 @@ public class KeyboardSet { } } private Keyboard getKeyboard(Context context, ElementParams elementParams, KeyboardId id) { final Resources res = context.getResources(); private Keyboard getKeyboard(Context context, ElementParams elementParams, final KeyboardId id) { final SoftReference<Keyboard> ref = sKeyboardCache.get(id); Keyboard keyboard = (ref == null) ? null : ref.get(); if (keyboard == null) { final Locale savedLocale = LocaleUtils.setSystemLocale(res, id.mLocale); try { final Keyboard.Builder<Keyboard.Params> builder = new Keyboard.Builder<Keyboard.Params>(context, new Keyboard.Params()); new Keyboard.Builder<Keyboard.Params>(mContext, new Keyboard.Params()); if (id.isAlphabetKeyboard()) { builder.setAutoGenerate(sKeysCache); } builder.load(elementParams.mKeyboardXmlId, id); final int keyboardXmlId = elementParams.mKeyboardXmlId; final RunInLocale<Void> job = new RunInLocale<Void>() { @Override protected Void job(Resources res) { builder.load(keyboardXmlId, id); return null; } }; job.runInLocale(context.getResources(), id.mLocale); builder.setTouchPositionCorrectionEnabled(mParams.mTouchPositionCorrectionEnabled); builder.setProximityCharsCorrectionEnabled( elementParams.mProximityCharsCorrectionEnabled); keyboard = builder.build(); } finally { LocaleUtils.setSystemLocale(res, savedLocale); } sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard)); if (DEBUG_CACHE) { Loading Loading @@ -271,16 +275,20 @@ public class KeyboardSet { if (mParams.mLocale == null) throw new RuntimeException("KeyboardSet subtype is not specified"); final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, mParams.mLocale); final RunInLocale<Void> job = new RunInLocale<Void>() { @Override protected Void job(Resources res) { try { parseKeyboardSet(mResources, R.xml.keyboard_set); parseKeyboardSet(res, R.xml.keyboard_set); } catch (Exception e) { throw new RuntimeException(e.getMessage() + " in " + mResources.getResourceName(R.xml.keyboard_set) + res.getResourceName(R.xml.keyboard_set) + " of locale " + mParams.mLocale); } finally { LocaleUtils.setSystemLocale(mResources, savedLocale); } return null; } }; job.runInLocale(mResources, mParams.mLocale); return new KeyboardSet(mContext, mParams); } Loading java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +9 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.util.Log; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import java.io.File; import java.util.ArrayList; import java.util.Locale; Loading Loading @@ -154,11 +156,13 @@ class BinaryDictionaryGetter { */ private static AssetFileAddress loadFallbackResource(final Context context, final int fallbackResId, final Locale locale) { final Resources res = context.getResources(); final Locale savedLocale = LocaleUtils.setSystemLocale(res, locale); final AssetFileDescriptor afd = res.openRawResourceFd(fallbackResId); LocaleUtils.setSystemLocale(res, savedLocale); final RunInLocale<AssetFileDescriptor> job = new RunInLocale<AssetFileDescriptor>() { @Override protected AssetFileDescriptor job(Resources res) { return res.openRawResourceFd(fallbackResId); } }; final AssetFileDescriptor afd = job.runInLocale(context.getResources(), locale); if (afd == null) { Log.e(TAG, "Found the resource but cannot read it. Is it compressed? resId=" + fallbackResId); Loading java/src/com/android/inputmethod/latin/DictionaryFactory.java +40 −38 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.util.Log; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import java.io.File; import java.util.ArrayList; import java.util.LinkedList; Loading @@ -30,7 +32,6 @@ import java.util.Locale; * Factory for dictionary instances. */ public class DictionaryFactory { private static String TAG = DictionaryFactory.class.getSimpleName(); /** Loading Loading @@ -98,14 +99,13 @@ public class DictionaryFactory { final int resId, final Locale locale) { AssetFileDescriptor afd = null; try { final Resources res = context.getResources(); if (null != locale) { final Locale savedLocale = LocaleUtils.setSystemLocale(res, locale); afd = res.openRawResourceFd(resId); LocaleUtils.setSystemLocale(res, savedLocale); } else { afd = res.openRawResourceFd(resId); final RunInLocale<AssetFileDescriptor> job = new RunInLocale<AssetFileDescriptor>() { @Override protected AssetFileDescriptor job(Resources res) { return res.openRawResourceFd(resId); } }; afd = job.runInLocale(context.getResources(), locale); if (afd == null) { Log.e(TAG, "Found the resource but it is compressed. resId=" + resId); return null; Loading Loading @@ -161,9 +161,9 @@ public class DictionaryFactory { * @return whether a (non-placeholder) dictionary is available or not. */ public static boolean isDictionaryAvailable(Context context, Locale locale) { final Resources res = context.getResources(); final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); final RunInLocale<Boolean> job = new RunInLocale<Boolean>() { @Override protected Boolean job(Resources res) { final int resourceId = getMainDictionaryResourceId(res); final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); final boolean hasDictionary = isFullDictionary(afd); Loading @@ -172,16 +172,17 @@ public class DictionaryFactory { } catch (java.io.IOException e) { /* Um, what can we do here exactly? */ } LocaleUtils.setSystemLocale(res, saveLocale); return hasDictionary; } }; return job.runInLocale(context.getResources(), locale); } // TODO: Do not use the size of the dictionary as an unique dictionary ID. public static Long getDictionaryId(final Context context, final Locale locale) { final Resources res = context.getResources(); final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); final RunInLocale<Long> job = new RunInLocale<Long>() { @Override protected Long job(Resources res) { final int resourceId = getMainDictionaryResourceId(res); final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH) Loading @@ -191,10 +192,11 @@ public class DictionaryFactory { if (null != afd) afd.close(); } catch (java.io.IOException e) { } LocaleUtils.setSystemLocale(res, saveLocale); return size; } }; return job.runInLocale(context.getResources(), locale); } // TODO: Find the Right Way to find out whether the resource is a placeholder or not. // Suggestion : strip the locale, open the placeholder file and store its offset. Loading java/src/com/android/inputmethod/latin/LatinIME.java +35 −24 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.suggestions.SuggestionsView; Loading Loading @@ -478,7 +479,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Has to be package-visible for unit tests /* package */ void loadSettings() { if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); mSettingsValues = new SettingsValues(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr()); final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() { @Override protected SettingsValues job(Resources res) { return new SettingsValues(mPrefs, LatinIME.this); } }; mSettingsValues = job.runInLocale(mResources, mSubtypeSwitcher.getInputLocale()); mFeedbackManager = new AudioAndHapticFeedbackManager(this, mSettingsValues); resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); } Loading @@ -487,8 +494,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); final Locale keyboardLocale = mSubtypeSwitcher.getInputLocale(); final Resources res = mResources; final Locale savedLocale = LocaleUtils.setSystemLocale(res, keyboardLocale); final Context context = this; final RunInLocale<Void> job = new RunInLocale<Void>() { @Override protected Void job(Resources res) { final ContactsDictionary oldContactsDictionary; if (mSuggest != null) { oldContactsDictionary = mSuggest.getContactsDictionary(); Loading @@ -498,22 +507,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } int mainDicResId = DictionaryFactory.getMainDictionaryResourceId(res); mSuggest = new Suggest(this, mainDicResId, keyboardLocale); mSuggest = new Suggest(context, mainDicResId, keyboardLocale); if (mSettingsValues.mAutoCorrectEnabled) { mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold); } mUserDictionary = new UserDictionary(this, localeStr); mUserDictionary = new UserDictionary(context, localeStr); mSuggest.setUserDictionary(mUserDictionary); mIsUserDictionaryAvailable = mUserDictionary.isEnabled(); resetContactsDictionary(oldContactsDictionary); mUserHistoryDictionary = new UserHistoryDictionary(this, localeStr, Suggest.DIC_USER_HISTORY); = new UserHistoryDictionary(context, localeStr, Suggest.DIC_USER_HISTORY); mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); LocaleUtils.setSystemLocale(res, savedLocale); return null; } }; job.runInLocale(mResources, keyboardLocale); } /** Loading java/src/com/android/inputmethod/latin/LocaleUtils.java +29 −14 Original line number Diff line number Diff line Loading @@ -161,21 +161,36 @@ public class LocaleUtils { return LOCALE_MATCH <= level; } static final Object sLockForRunInLocale = new Object(); public abstract static class RunInLocale<T> { protected abstract T job(Resources res); /** * Sets the system locale for this process. * Execute {@link #job(Resources)} method in specified system locale exclusively. * * @param res the resources to use. Pass current resources. * @param newLocale the locale to change to. * @return the old locale. * @param newLocale the locale to change to * @return the value returned from {@link #job(Resources)}. */ public static synchronized Locale setSystemLocale(final Resources res, final Locale newLocale) { public T runInLocale(final Resources res, final Locale newLocale) { synchronized (sLockForRunInLocale) { final Configuration conf = res.getConfiguration(); final Locale oldLocale = conf.locale; try { if (newLocale != null && !newLocale.equals(oldLocale)) { conf.locale = newLocale; res.updateConfiguration(conf, res.getDisplayMetrics()); } return oldLocale; return job(res); } finally { if (newLocale != null && !newLocale.equals(oldLocale)) { conf.locale = oldLocale; res.updateConfiguration(conf, res.getDisplayMetrics()); } } } } } private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>(); Loading Loading
java/src/com/android/inputmethod/keyboard/KeyboardSet.java +35 −27 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ import com.android.inputmethod.keyboard.KeyboardSet.Params.ElementParams; import com.android.inputmethod.latin.InputTypeUtils; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.XmlParseUtils; Loading Loading @@ -66,6 +66,7 @@ public class KeyboardSet { public static class KeyboardSetException extends RuntimeException { public final KeyboardId mKeyboardId; public KeyboardSetException(Throwable cause, KeyboardId keyboardId) { super(cause); mKeyboardId = keyboardId; Loading Loading @@ -161,26 +162,29 @@ public class KeyboardSet { } } private Keyboard getKeyboard(Context context, ElementParams elementParams, KeyboardId id) { final Resources res = context.getResources(); private Keyboard getKeyboard(Context context, ElementParams elementParams, final KeyboardId id) { final SoftReference<Keyboard> ref = sKeyboardCache.get(id); Keyboard keyboard = (ref == null) ? null : ref.get(); if (keyboard == null) { final Locale savedLocale = LocaleUtils.setSystemLocale(res, id.mLocale); try { final Keyboard.Builder<Keyboard.Params> builder = new Keyboard.Builder<Keyboard.Params>(context, new Keyboard.Params()); new Keyboard.Builder<Keyboard.Params>(mContext, new Keyboard.Params()); if (id.isAlphabetKeyboard()) { builder.setAutoGenerate(sKeysCache); } builder.load(elementParams.mKeyboardXmlId, id); final int keyboardXmlId = elementParams.mKeyboardXmlId; final RunInLocale<Void> job = new RunInLocale<Void>() { @Override protected Void job(Resources res) { builder.load(keyboardXmlId, id); return null; } }; job.runInLocale(context.getResources(), id.mLocale); builder.setTouchPositionCorrectionEnabled(mParams.mTouchPositionCorrectionEnabled); builder.setProximityCharsCorrectionEnabled( elementParams.mProximityCharsCorrectionEnabled); keyboard = builder.build(); } finally { LocaleUtils.setSystemLocale(res, savedLocale); } sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard)); if (DEBUG_CACHE) { Loading Loading @@ -271,16 +275,20 @@ public class KeyboardSet { if (mParams.mLocale == null) throw new RuntimeException("KeyboardSet subtype is not specified"); final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, mParams.mLocale); final RunInLocale<Void> job = new RunInLocale<Void>() { @Override protected Void job(Resources res) { try { parseKeyboardSet(mResources, R.xml.keyboard_set); parseKeyboardSet(res, R.xml.keyboard_set); } catch (Exception e) { throw new RuntimeException(e.getMessage() + " in " + mResources.getResourceName(R.xml.keyboard_set) + res.getResourceName(R.xml.keyboard_set) + " of locale " + mParams.mLocale); } finally { LocaleUtils.setSystemLocale(mResources, savedLocale); } return null; } }; job.runInLocale(mResources, mParams.mLocale); return new KeyboardSet(mContext, mParams); } Loading
java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +9 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.util.Log; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import java.io.File; import java.util.ArrayList; import java.util.Locale; Loading Loading @@ -154,11 +156,13 @@ class BinaryDictionaryGetter { */ private static AssetFileAddress loadFallbackResource(final Context context, final int fallbackResId, final Locale locale) { final Resources res = context.getResources(); final Locale savedLocale = LocaleUtils.setSystemLocale(res, locale); final AssetFileDescriptor afd = res.openRawResourceFd(fallbackResId); LocaleUtils.setSystemLocale(res, savedLocale); final RunInLocale<AssetFileDescriptor> job = new RunInLocale<AssetFileDescriptor>() { @Override protected AssetFileDescriptor job(Resources res) { return res.openRawResourceFd(fallbackResId); } }; final AssetFileDescriptor afd = job.runInLocale(context.getResources(), locale); if (afd == null) { Log.e(TAG, "Found the resource but cannot read it. Is it compressed? resId=" + fallbackResId); Loading
java/src/com/android/inputmethod/latin/DictionaryFactory.java +40 −38 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.util.Log; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import java.io.File; import java.util.ArrayList; import java.util.LinkedList; Loading @@ -30,7 +32,6 @@ import java.util.Locale; * Factory for dictionary instances. */ public class DictionaryFactory { private static String TAG = DictionaryFactory.class.getSimpleName(); /** Loading Loading @@ -98,14 +99,13 @@ public class DictionaryFactory { final int resId, final Locale locale) { AssetFileDescriptor afd = null; try { final Resources res = context.getResources(); if (null != locale) { final Locale savedLocale = LocaleUtils.setSystemLocale(res, locale); afd = res.openRawResourceFd(resId); LocaleUtils.setSystemLocale(res, savedLocale); } else { afd = res.openRawResourceFd(resId); final RunInLocale<AssetFileDescriptor> job = new RunInLocale<AssetFileDescriptor>() { @Override protected AssetFileDescriptor job(Resources res) { return res.openRawResourceFd(resId); } }; afd = job.runInLocale(context.getResources(), locale); if (afd == null) { Log.e(TAG, "Found the resource but it is compressed. resId=" + resId); return null; Loading Loading @@ -161,9 +161,9 @@ public class DictionaryFactory { * @return whether a (non-placeholder) dictionary is available or not. */ public static boolean isDictionaryAvailable(Context context, Locale locale) { final Resources res = context.getResources(); final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); final RunInLocale<Boolean> job = new RunInLocale<Boolean>() { @Override protected Boolean job(Resources res) { final int resourceId = getMainDictionaryResourceId(res); final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); final boolean hasDictionary = isFullDictionary(afd); Loading @@ -172,16 +172,17 @@ public class DictionaryFactory { } catch (java.io.IOException e) { /* Um, what can we do here exactly? */ } LocaleUtils.setSystemLocale(res, saveLocale); return hasDictionary; } }; return job.runInLocale(context.getResources(), locale); } // TODO: Do not use the size of the dictionary as an unique dictionary ID. public static Long getDictionaryId(final Context context, final Locale locale) { final Resources res = context.getResources(); final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); final RunInLocale<Long> job = new RunInLocale<Long>() { @Override protected Long job(Resources res) { final int resourceId = getMainDictionaryResourceId(res); final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH) Loading @@ -191,10 +192,11 @@ public class DictionaryFactory { if (null != afd) afd.close(); } catch (java.io.IOException e) { } LocaleUtils.setSystemLocale(res, saveLocale); return size; } }; return job.runInLocale(context.getResources(), locale); } // TODO: Find the Right Way to find out whether the resource is a placeholder or not. // Suggestion : strip the locale, open the placeholder file and store its offset. Loading
java/src/com/android/inputmethod/latin/LatinIME.java +35 −24 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.suggestions.SuggestionsView; Loading Loading @@ -478,7 +479,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Has to be package-visible for unit tests /* package */ void loadSettings() { if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); mSettingsValues = new SettingsValues(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr()); final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() { @Override protected SettingsValues job(Resources res) { return new SettingsValues(mPrefs, LatinIME.this); } }; mSettingsValues = job.runInLocale(mResources, mSubtypeSwitcher.getInputLocale()); mFeedbackManager = new AudioAndHapticFeedbackManager(this, mSettingsValues); resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); } Loading @@ -487,8 +494,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); final Locale keyboardLocale = mSubtypeSwitcher.getInputLocale(); final Resources res = mResources; final Locale savedLocale = LocaleUtils.setSystemLocale(res, keyboardLocale); final Context context = this; final RunInLocale<Void> job = new RunInLocale<Void>() { @Override protected Void job(Resources res) { final ContactsDictionary oldContactsDictionary; if (mSuggest != null) { oldContactsDictionary = mSuggest.getContactsDictionary(); Loading @@ -498,22 +507,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } int mainDicResId = DictionaryFactory.getMainDictionaryResourceId(res); mSuggest = new Suggest(this, mainDicResId, keyboardLocale); mSuggest = new Suggest(context, mainDicResId, keyboardLocale); if (mSettingsValues.mAutoCorrectEnabled) { mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold); } mUserDictionary = new UserDictionary(this, localeStr); mUserDictionary = new UserDictionary(context, localeStr); mSuggest.setUserDictionary(mUserDictionary); mIsUserDictionaryAvailable = mUserDictionary.isEnabled(); resetContactsDictionary(oldContactsDictionary); mUserHistoryDictionary = new UserHistoryDictionary(this, localeStr, Suggest.DIC_USER_HISTORY); = new UserHistoryDictionary(context, localeStr, Suggest.DIC_USER_HISTORY); mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); LocaleUtils.setSystemLocale(res, savedLocale); return null; } }; job.runInLocale(mResources, keyboardLocale); } /** Loading
java/src/com/android/inputmethod/latin/LocaleUtils.java +29 −14 Original line number Diff line number Diff line Loading @@ -161,21 +161,36 @@ public class LocaleUtils { return LOCALE_MATCH <= level; } static final Object sLockForRunInLocale = new Object(); public abstract static class RunInLocale<T> { protected abstract T job(Resources res); /** * Sets the system locale for this process. * Execute {@link #job(Resources)} method in specified system locale exclusively. * * @param res the resources to use. Pass current resources. * @param newLocale the locale to change to. * @return the old locale. * @param newLocale the locale to change to * @return the value returned from {@link #job(Resources)}. */ public static synchronized Locale setSystemLocale(final Resources res, final Locale newLocale) { public T runInLocale(final Resources res, final Locale newLocale) { synchronized (sLockForRunInLocale) { final Configuration conf = res.getConfiguration(); final Locale oldLocale = conf.locale; try { if (newLocale != null && !newLocale.equals(oldLocale)) { conf.locale = newLocale; res.updateConfiguration(conf, res.getDisplayMetrics()); } return oldLocale; return job(res); } finally { if (newLocale != null && !newLocale.equals(oldLocale)) { conf.locale = oldLocale; res.updateConfiguration(conf, res.getDisplayMetrics()); } } } } } private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>(); Loading