如果不重新启动应用,则不会保存SharedPreferences

时间:2013-07-04 05:45:34

标签: java android eclipse

当应用程序运行时,使用什么代码来检测SharedPreferences中所做的任何更改? 我的SharedPreferences中所做的更改仅在应用关闭并重新启动时才会反映出来。在同一会话期间不会更改。

要获取首选项,请使用以下代码 在SettingsActivity.java中

@Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_general);
        bindPreferenceSummaryToValue(findPreference("unit_type"));
    }

和activity.java

final SharedPreferences unitpreference = PreferenceManager.getDefaultSharedPreferences(this);
final String unitstring = unitpreference.getString("unit_type", "");

但是我应该在哪里以及在哪里编写一些代码以便立即进行更改?

完整更新的代码: SettingsActivity.java

package com.basic.mileagecalculatorwithsettings;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import android.support.v4.app.NavUtils;
import java.util.List;

public class SettingsActivity extends PreferenceActivity 
{

private static final boolean ALWAYS_SIMPLE_PREFS = false;
protected static final String TAG = null;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setupActionBar();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        // Display the fragment as the main content.
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new GeneralPreferenceFragment())
                .commit();
    } else {
        // use normal preferences
        setupSimplePreferencesScreen();

        PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(mPrefsListener);
    }
}

SharedPreferences.OnSharedPreferenceChangeListener mPrefsListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
    @Override
    public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
        if ("unit_type".equals(key)) {
            Log.v(TAG, "Setting has been changed!");
        }
    }

};
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() 
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
    {
        getActionBar().setDisplayHomeAsUpEnabled(true);
        }
}
    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {
        switch (item.getItemId()) 
        {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onPostCreate(Bundle savedInstanceState) 
    {
        super.onPostCreate(savedInstanceState);

        //setupSimplePreferencesScreen();
    }
    private void setupSimplePreferencesScreen() {
        if (!isSimplePreferences(this)) {
            return;
        }
        addPreferencesFromResource(R.xml.pref_general);}
    @Override
    public boolean onIsMultiPane() 
    {
        return isXLargeTablet(this) && !isSimplePreferences(this);
    }
    private static boolean isXLargeTablet(Context context) 
    {
        return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
    }
    private static boolean isSimplePreferences(Context context) 
    {
        return ALWAYS_SIMPLE_PREFS
                || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
                || !isXLargeTablet(context);
    }
    @Override
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void onBuildHeaders(List<Header> target) 
    {
        if (!isSimplePreferences(this)) 
        {
            //loadHeadersFromResource(R.xml.pref_headers, target);
        }
    };
    private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object value) 
        {
            String stringValue = value.toString();

            if (preference instanceof ListPreference) 
            {
                ListPreference listPreference = (ListPreference) preference;
                int index = listPreference.findIndexOfValue(stringValue);
                preference.setSummary(index >= 0 ? listPreference.getEntries()[index]:null);
            }
            else if (preference instanceof RingtonePreference) 
            {
                if (TextUtils.isEmpty(stringValue))
                {
                    //preference.setSummary(R.string.pref_ringtone_silent);
                }
                else 
                {
                    Ringtone ringtone = RingtoneManager.getRingtone(
                            preference.getContext(), Uri.parse(stringValue));
                    if (ringtone == null) 
                    {preference.setSummary(null);}
                    else 
                    {
                        String name = ringtone.getTitle(preference.getContext());
                        preference.setSummary(name);
                    }
                }
            }
            else 
            {
                preference.setSummary(stringValue);
            }
            return true;
        }
};
private static void bindPreferenceSummaryToValue(Preference preference) 
{
    preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
    sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,PreferenceManager.getDefaultSharedPreferences(preference.getContext()).getString(preference.getKey(),""));
}
@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);
        bindPreferenceSummaryToValue(findPreference("example_list"));
        bindPreferenceSummaryToValue(findPreference("fuel_type"));
        bindPreferenceSummaryToValue(findPreference("unit_type"));

    }
    @Override
    public void onResume() {
        super.onResume();


    }
    public void onPause(Bundle savedInstanceState)
    {
      super.onPause();
      addPreferencesFromResource(R.xml.pref_general);

     }
}
}

pref_general.xml     

<ListPreference
    android:defaultValue="1"
    android:entries="@array/pref_example_list_titles"
    android:entryValues="@array/pref_example_list_values"
    android:key="city_list"
    android:negativeButtonText="@null"
    android:positiveButtonText="@null"
    android:title="@string/pref_title_add_friends_to_messages" android:enabled="true"/>

<ListPreference
    android:defaultValue="1"
    android:entries="@array/pref_fuel_type_titles"
    android:entryValues="@array/pref_fuel_type_values"
    android:key="fuel_type"
    android:negativeButtonText="@null"
    android:positiveButtonText="@null"
    android:title="@string/pref_title_select_fuel" android:enabled="true"/>

<ListPreference
    android:defaultValue="1"
    android:entries="@array/pref_units_titles"
    android:entryValues="@array/pref_units_values"
    android:key="unit_type"
    android:negativeButtonText="@null"
    android:positiveButtonText="@null"
    android:title="@string/pref_title_unit" android:enabled="true"/>

</PreferenceScreen>

2 个答案:

答案 0 :(得分:1)

我已经检查了您的代码,看起来您根本就没有创建GeneralPreferenceFragment。所以,如果我添加以下内容:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setupActionBar();

    // Display the fragment as the main content.
    getFragmentManager().beginTransaction()
            .replace(android.R.id.content, new GeneralPreferenceFragment())
            .commit();
}

并删除setupSimplePreferencesScreen()电话,然后在最新的Android版本上运行正常。

如果您需要支持旧版本,我会采用以下方式:

public class SettingsActivity extends PreferenceActivity {

    private static final boolean ALWAYS_SIMPLE_PREFS = false;
    protected static final String TAG = null;

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupActionBar();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            // Display the fragment as the main content.
            getFragmentManager().beginTransaction()
                    .replace(android.R.id.content, new GeneralPreferenceFragment())
                    .commit();
        } else {
            // use normal preferences
            setupSimplePreferencesScreen();

            PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(mPrefsListener);
        }
    }

    SharedPreferences.OnSharedPreferenceChangeListener mPrefsListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
        @Override
        public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
            Log.v(TAG, "Setting has been changed!");
        }
    };

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void setupActionBar()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        {
            getActionBar().setDisplayHomeAsUpEnabled(true);
        }
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
            case android.R.id.home:
                //NavUtils.navigateUpFromSameTask(this);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);

        //setupSimplePreferencesScreen();
    }
    private void setupSimplePreferencesScreen() {
        if (!isSimplePreferences(this)) {
            return;
        }
        addPreferencesFromResource(R.xml.pref_general);
    }

    @Override
    public boolean onIsMultiPane() {
        return isXLargeTablet(this) && !isSimplePreferences(this);
    }

    private static boolean isXLargeTablet(Context context) {
        return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
    }
    private static boolean isSimplePreferences(Context context) {
        return ALWAYS_SIMPLE_PREFS
                || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
                || !isXLargeTablet(context);
    }

    @Override
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void onBuildHeaders(List<Header> target) {
        if (!isSimplePreferences(this)) {
            //loadHeadersFromResource(R.xml.pref_headers, target);
        }
    }

    private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object value) {
            Log.v(TAG, "Setting has been changed!");

            String stringValue = value.toString();

            if (preference instanceof ListPreference) {
                ListPreference listPreference = (ListPreference) preference;
                int index = listPreference.findIndexOfValue(stringValue);
                preference.setSummary(index >= 0 ? listPreference.getEntries()[index]:null);
            }
            else if (preference instanceof RingtonePreference) {
                if (TextUtils.isEmpty(stringValue)) {
                    //preference.setSummary(R.string.pref_ringtone_silent);
                } else {
                    Ringtone ringtone = RingtoneManager.getRingtone(
                            preference.getContext(), Uri.parse(stringValue));
                    if (ringtone == null) {
                        preference.setSummary(null);
                    } else {
                        String name = ringtone.getTitle(preference.getContext());
                        preference.setSummary(name);
                    }
                }
            } else {
                preference.setSummary(stringValue);
            }

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

    @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);
            bindPreferenceSummaryToValue(findPreference("example_list"));
            bindPreferenceSummaryToValue(findPreference("fuel_type"));
            bindPreferenceSummaryToValue(findPreference("unit_type"));
        }

        @Override
        public void onResume() {
            super.onResume();
        }

        public void onPause(Bundle savedInstanceState) {
            super.onPause();
            addPreferencesFromResource(R.xml.pref_general);
        }
    }
}

我使用以下pref_general.xml检查了该代码:

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory
        android:title="Title category">

        <ListPreference
            android:key="example_list"
            android:title="example_list"
            android:summary="example_list"
            android:entries="@array/entries_list_preference"
            android:entryValues="@array/entryvalues_list_preference"
            android:dialogTitle="example_list" />
        <ListPreference
            android:key="fuel_type"
            android:title="fuel_type"
            android:summary="fuel_type"
            android:entries="@array/entries_list_preference"
            android:entryValues="@array/entryvalues_list_preference"
            android:dialogTitle="fuel_type" />
        <ListPreference
            android:key="unit_type"
            android:title="unit_type"
            android:summary="unit_type"
            android:entries="@array/entries_list_preference"
            android:entryValues="@array/entryvalues_list_preference"
            android:dialogTitle="unit_type" />
    </PreferenceCategory>

</PreferenceScreen>

能够观察Setting has been changed!日志。

基本上,您的代码存在的问题是,您既不会创建GeneralPreferenceFragment,也不会使用SharedPreferences.OnSharedPreferenceChangeListener。我建议让代码更具可读性,然后你可能更容易发现问题。

答案 1 :(得分:0)

如果在关闭应用程序之前存在SharedPreferences未保存的问题,则可能未提交/应用更改(如用户1283633在其评论中所述)。

来自SharedPrecerences.Editor的JavaDoc:

  

用于修改SharedPreferences对象中的值的接口。所有   您在编辑器中所做的更改是批处理的,而不是复制回到   原始SharedPreferences,直到您调用commit()或apply()

我假设您在向SharedPreferences.Editor商店添加数据时使用SharedPreferences,在完成添加数据后,您可以尝试拨打commit()apply() Editor。如果您关心结果,请选择commit()(返回布尔值),否则您可以使用apply()(无效)。