在运行时设置语言时,4.4中的内存(可能是上下文)泄漏

时间:2017-01-05 06:21:10

标签: android android-activity

我有一个开始活动(A)和语言选择活动(B)。活动A具有语言指示,在单击时启动活动B.活动B具有语言列表视图,点击后在共享首选项中设置语言代码并启动活动A.活动A覆盖attachBaseContext方法,读取语言首选项,用正确的语言环境包装上下文并将其返回。 但如果我尝试在KitKat(4.4)上多次更改语言,应用程序会因内存不足而崩溃。 Memory usage工具显示每次语言更改时有10个上下文和数字增加(我猜这是崩溃的原因)。我如何找到上下文泄漏的问题?

方法如下。 从A到B:

        //goto language selection activity
        Intent selectLanguageIntent = new Intent(StartingActivity.this, LanguageSelectionActivity.class);
        //disables going back to previous activity
        selectLanguageIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(selectLanguageIntent);

        finish();

从B到A:

//get language name from clicked item
            String language = (String) adapterView.getItemAtPosition(i);

            //get shared preferences
            SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(getString(R.string.language_setting_preferences_file), Context.MODE_PRIVATE);
            sharedPreferences.edit().putString("lang", language).apply();

            //goto starting activity
            Intent startingActivity = new Intent(LanguageSelectionActivity.this, StartingActivity.class);
            //disables going back to previous activity
            startingActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(startingActivity);

            finish();

覆盖attachBaseContext

    @Override
    protected void attachBaseContext(Context newBase) {
        //get shared preferences
        SharedPreferences languageSettingPreferences = newBase.getSharedPreferences(newBase.getString(R.string.language_setting_preferences_file), Context.MODE_PRIVATE);

        //read language stored in shared preferences
        myLanguage = languageSettingPreferences.getString("lang", null);


        //check if any language is stored
        if (myLanguage != null) {

            //if stored, wrap a context with stored locale
            super.attachBaseContext(LangChangeContextWrapper.wrap(newBase, LangChangeContextWrapper.getLanguageCode(myLanguage)));

        } else {

            //if not stored, return the same context
            super.attachBaseContext(newBase);

        }
    }

班级LangChangeContextWrapper

public class LangChangeContextWrapper extends ContextWrapper {

    static Map<String, String> languageCodes;

    //default constructor
    public LangChangeContextWrapper(Context base) {
        super(base);
    }

    //wraps a context with requested locale
    public static ContextWrapper wrap(Context context, String language) {

        Configuration config = context.getResources().getConfiguration();
        Locale sysLocale;

        sysLocale = getSystemLocale(config);

        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        setSystemLocale(config, locale);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            context = context.createConfigurationContext(config);
        } else {
            context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
        }


        return new LangChangeContextWrapperNew(context);

    }

    //gets default system locale
    public static Locale getSystemLocale(Configuration config) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return config.getLocales().get(0);
        } else {
            return Locale.getDefault();
        }
    }

    //sets systems locale
    public static void setSystemLocale(Configuration config, Locale locale) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            config.setLocale(locale);
        } else {
            config.locale = locale;
        }
    }

    //returns language code for language name
    public static String getLanguageCode(String language) {

        //creates hashmap of languages
        fillUpLanguageCodes();

        return languageCodes.get(language);
    }

    //returns hashmap of languages
    public static Map<String, String> getLanguageCodesMap() {
        //creates hashmap of languages
        fillUpLanguageCodes();

        return languageCodes;
    }

    //creates hashmap of languages
    public static void fillUpLanguageCodes() {

        //only creates once
        if (languageCodes == null) {

            //map of supported languages
            languageCodes = new LinkedHashMap<>();
            languageCodes.put("English", "en");
            languageCodes.put("Lietuviškai", "lt");
        }
    }

0 个答案:

没有答案