如何在Preference.OnPreferenceChangeListener()中正确调用该方法

时间:2019-04-10 09:03:45

标签: android android-preferences preferenceactivity

如何在SettingActivity的上下文中从SettingActivity的Preference.OnPreferenceChangeListener()中正确调用该方法? 如何从PreferenceActivity(SettingsActivity)获取上下文?调用方法'App.localeManager.setNewLocale(this,language);'时出现异常,在此方法中,我尝试从contex获取资源,但是cotntext.getResource()为null。
例外:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: ua.soe.billing.android, PID: 16130
              java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                  at android.content.ContextWrapper.getResources(ContextWrapper.java:86)
                  at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:74)
                  at local.test.i.so.LocaleManager.updateResources(LocaleManager.java:58)
                  at local.test.i.so.LocaleManager.setNewLocale(LocaleManager.java:38)
                  at local.test.i.so.SettingsActivity.setNewLocale(SettingsActivity.java:136)
                  at local.test.i.so.SettingsActivity$1.onPreferenceChange(SettingsActivity.java:129)
                  at android.preference.Preference.callChangeListener(Preference.java:981)
                  at android.preference.ListPreference.onDialogClosed(ListPreference.java:286)
                  at android.preference.DialogPreference.onDismiss(DialogPreference.java:391)
                  at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1265)
                  at android.os.Handler.dispatchMessage(Handler.java:111)
                  at android.os.Looper.loop(Looper.java:194)
                  at android.app.ActivityThread.main(ActivityThread.java:5898)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1019)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:814)

SettingsActivity

public class SettingsActivity extends BasePreferenceActivity {
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {
        String stringValue = value.toString();
        System.out.println("system language: " + Locale.getDefault().getDisplayLanguage());
        String s = Locale.getDefault().getLanguage();
        System.out.println("language: " + preference.getSharedPreferences().getString("language",""));
        String lan = preference.getSharedPreferences().getString("language","");
        int index = 0;
        CharSequence[] entries = new CharSequence[0];
        CharSequence[] entryValues = new CharSequence[0];
        if (preference instanceof ListPreference) {
            // For list preferences, look up the correct display value in
            // the preference's 'entries' list.
            ListPreference listPreference = (ListPreference) preference;
            entries = listPreference.getEntries();
            entryValues = listPreference.getEntryValues();
            if(lan.equals("")||lan.equals("null")) {
                for (int i = 0; i < entryValues.length; i++) {
                    if (entryValues[i].toString().toLowerCase().equals(s.toLowerCase())){
                        index = listPreference.findIndexOfValue(entryValues[i].toString());
                        break;
                    }
                }
            }else {
                index = listPreference.findIndexOfValue(stringValue);
            }
            ((ListPreference) preference).setValue(entryValues[index].toString());
            preference.setSummary(
                    index >= 0
                            ? listPreference.getEntries()[index]
                            : null);

        } else {

            preference.setSummary(stringValue);
        }
        if(!lan.equals(entryValues[index].toString())) {
            SettingsActivity settingsActivity = new SettingsActivity();
            settingsActivity.setNewLocale(entryValues[index].toString(), true);
        }
        return true;
    }
};

public boolean setNewLocale(String language, boolean restartProcess) {
    App.localeManager.setNewLocale(this, language);

    Intent i = new Intent(this, SettingsActivity.class);
    startActivity(i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK));

    if (restartProcess) {
        System.exit(0);
    } else {
        Toast.makeText(this, "Activity restarted", Toast.LENGTH_SHORT).show();
    }
    return true;
}

private static void bindPreferenceSummaryToValue(Preference preference) {
    preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
    sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
            PreferenceManager
                    .getDefaultSharedPreferences(preference.getContext())
                    .getString(preference.getKey(), ""));
    System.out.println("");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setupActionBar();
    getFragmentManager().beginTransaction().replace(android.R.id.content,
            new GeneralPreferenceFragment()).commit();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == android.R.id.home) {
        finish();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void setupActionBar() {
    ActionBar actionBar = getDelegate().getSupportActionBar();
    if (actionBar != null) {
        // Show the Up button in the action bar.
        actionBar.setDisplayHomeAsUpEnabled(true);
    }
    actionBar.setTitle(R.string.menu_settings);
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPreferenceFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_general);
        setHasOptionsMenu(true);
        bindPreferenceSummaryToValue(findPreference("language"));
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            startActivity(new Intent(getActivity(), SettingsActivity.class));
            return true;
        }
        return super.onOptionsItemSelected(item);


       }
    }
}

LocaleManager:

public Context setNewLocale(Context c, String language) {
    persistLanguage(language);
    return updateResources(c, language);
}
private Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);
    Resources res = context.getResources();
    Configuration config = new Configuration(res.getConfiguration());
    if (Utility.isAtLeastVersion(JELLY_BEAN_MR1)) {
        config.setLocale(locale);
        context = context.createConfigurationContext(config);
    } else {
        config.locale = locale;
        res.updateConfiguration(config, res.getDisplayMetrics());
    }
    return context;
}

1 个答案:

答案 0 :(得分:0)

您的代码中还有更多这个问题,但根本原因是:

SettingsActivity settingsActivity = new SettingsActivity();

您不得像这样实例化您的活动。您的活动必须在清单中声明,并且必须由Android本身或使用Intent启动。