离开PreferenceActivity,调用Activity仍然会读取旧的首选项?

时间:2012-04-13 21:00:19

标签: android sharedpreferences

我觉得我错过了一些明显的东西,但搜索带我去了几个不同的点击,所有这些都没有直接访问我的奇怪问题。

拥有主要活动和偏好活动的应用。添加一个'首选'类,简化了阅读和设置首选项。主要活动有一个选项菜单,可以进入首选项活动:

首选项类(包含相关性,如果我不使用此类来读取设置,则会发生相同的事情)。

public class Preferences
{
    public static SharedPreferences getPrefs(Context context)
    {
        SharedPreferences retCont = PreferenceManager.getDefaultSharedPreferences(context);
        return retCont;
    }

    /* Map Page: Show Satellite */
    public static boolean getMapShowSatellite(Context context)
    {
        return Preferences.getPrefs(context).getBoolean(Preferences.getString(context, R.string.option_showSatellite), false);
    }

    public static void setMapShowSatellite(Context context, boolean newValue)
    {
        Editor prefsEditor = Preferences.getPrefs(context).edit();
        prefsEditor.putBoolean(Preferences.getString(context, R.string.option_showSatellite), newValue);
        prefsEditor.commit();
    }
}

PreferencesActivity:

public class AppSettings extends PreferenceActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.app_preferences);

        ListPreference stationType = (ListPreference)this.findPreference(this.getString(R.string.option_filterStationType));
        stationType.setOnPreferenceChangeListener(this.stationOrderEnable());
    }
[...]
}

最后两行连接一个事件,根据一个人的选择启用/禁用其他首选项。这符合预期。 简单的主要活动和相关功能:

public class MainMapScreen extends MapActivity
{
    private void launchSettings()
    {
        Intent prefsIntent = new Intent(this.getApplicationContext(), AppSettings.class);
        this.startActivity(prefsIntent);
    }

    @Override
    protected void onResume()
    {
        super.onResume();

        Preferences.getMapShowSatellite(); // <-- Returns previous value.
        // Re-start the MyLocation Layer from tracking.
        this._mapView.requestLayout();
    }
[...]
}

好的,所以会发生什么,让我们说我们运行应用程序。在应用加载时,getMapShowSatellite()会返回True。进入PreferenceActivity,将该选项更改为False。按“返回”按钮退出PreferenceActivity。此时,将调用主要活动onResume()。此时获取getMapShowSatellite()将返回先前的True设置。退出并重新启动应用程序最终将返回预期的False

我没有手动调用.commit() - 并且认为我不需要,设置IS保存,我只是没有获得更新值。

我错过了什么? :) --Fox。

编辑2:小更新。我认为问题可能是静态调用 - 所以暂时我将我的Preferences类(上面)更改为实例化类,不再是静态的。我还在主要活动的onResume()调用中添加了以下代码:

//Try reloading preferences?
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
String test = sp.getString(Preferences.OPTION_FILTERSTATIONTYPE, "---");
Log.e("BMMaps", test);

此时从离开PreferenceActivity开始记录的内容是旧设置。手动阅读首选项文件向我显示.xml文件正在使用用户的新设置进行更新。

由于不明显,我迷上了谷歌的Maps API。因此,我必须指定两个不同的进程 - 一个用于主要活动(这个),另一个用于与此问题无关的活动。所有其他活动(包括PreferencesActivity)在其定义中都没有指定android:process=""

编辑3: 根据要求,这是数据首选项文件:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="com.tsqmadness.bmmaps.filterStationType">V-?</string>
    <boolean name="com.tsqmadness.bmmaps.deviceHasLocation" value="false" />
</map>

这是Preference存储XML文件:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="Map Options">
        <CheckBoxPreference android:key="com.tsqmadness.bmmaps.mapShowSatellite" android:order="1" android:summary="Whether or not to show satellite imagery on the map." android:summaryOff="Standard road map will be shown." android:summaryOn="Satellite imagery will be show." android:title="Show Satellite Layer?" />
        <CheckBoxPreference android:key="com.tsqmadness.bmmaps.mapShowScale" android:order="2" android:summary="Whether or not to show the distance bar on the map." android:summaryOff="The distance bar will not be shown on the map." android:summaryOn="The distance bar will be shown on the map." android:title="Show Map Scale?" />
        <CheckBoxPreference android:defaultValue="false" android:key="com.tsqmadness.bmmaps.useMetric" android:order="3" android:summary="Whether to use Metric os SI values." android:summaryOff="SI units (mi/ft) will be shown." android:summaryOn="Metric units (km/m) will be shown." android:title="Use Metric?" />
        <ListPreference android:dialogTitle="Station Load Delay" android:entries="@array/static_listDelayDisplay" android:entryValues="@array/static_listDelayValues" android:key="com.tsqmadness.bmmaps.mapBMDelay" android:negativeButtonText="Cancel" android:order="4" android:positiveButtonText="Save" android:summary="The delay after map panning before staions are loaded." android:title="Delay Before Loading" />
    </PreferenceCategory>
    <PreferenceCategory android:title="Control Station Filter">
        <ListPreference android:dialogTitle="Station Type" android:entries="@array/static_listStationTypeDisplay" android:entryValues="@array/static_listStationTypeValues" android:key="com.tsqmadness.bmmaps.filterStationType" android:negativeButtonText="Cancel" android:positiveButtonText="Save" android:summary="The station type to filter on." android:title="Station Type" android:order="1" />
        <ListPreference android:dialogTitle="Select Station Order" android:entries="@array/static_listStationHOrderDisplay" android:entryValues="@array/static_listStationHOrderValues" android:key="com.tsqmadness.bmmaps.filterStationOrder" android:negativeButtonText="Cancel" android:positiveButtonText="Save" android:summary="Station Order to filter by." android:title="Station Order" android:order="2" />
        <ListPreference android:dialogTitle="Select Station Stability" android:entries="@array/static_listStationStabilityDisplay" android:entryValues="@array/static_listStationStabilityValues" android:key="com.tsqmadness.bmmaps.filterStationStability" android:negativeButtonText="Cancel" android:positiveButtonText="Save" android:summary="Station stability to filter by." android:title="Station Stability" android:order="3" />
        <CheckBoxPreference android:key="com.tsqmadness.bmmaps.filterNonPub" android:summaryOff="Non-Publishable stations will not be shown." android:defaultValue="false" android:summaryOn="Non-Publishable stations will be shown on the map." android:order="4" android:title="Show Non-Publishable" />
    </PreferenceCategory>
    <Preference android:key="temp" android:title="Test" android:summary="Test Item">
        <intent android:targetClass="com.tsqmadness.bmmaps.activities.MainMapScreen" android:targetPackage="com.tsqmadness.bmmaps" />
    </Preference>
</PreferenceScreen>

更改filterStationType参数并点击PreferenceActivity中的后退按钮时,会将首选项文件从V-?更改为H-?。但是,从主活动的SharedPreferences中读取值仍会提供V-?,直到应用重启。啊,同样,我在PreferenceActivity中有一个OnPreferenceChangeListnener(),当值发生变化时会调用它。

最终编辑:显然,它是对给定活动使用命名的android:process。这需要Google Maps API允许同一个应用中的两个单独的MapActivity使用不同的设置。如果将PreferenceActivity移动到同一个命名进程,则上面的代码读取onResume()中的设置将返回正确的值。

2 个答案:

答案 0 :(得分:0)

由于所有内容都已检出,我的猜测是您的PreferenceActivity app_preferences.xml文件中的密钥R.string.option_showSatellite(无论该字符串是什么)都有一个拼写错误或不正确或未定义的密钥。这会导致两个键[不知道你]不同的名称,你认为它们指向相同的值。实际上,prefs活动使用一个键,而Preference类正在使用另一个键 - 导致两个不同的键和两个不同的值。

仔细检查您的钥匙。确保您没有使用文字"R.string.options_showSatellite"作为xml文件中的键,而是使用实际字符串。如果您想使用本地化版本,那么@string/options_showSatellite将适用于密钥。但是,密钥不需要本地化。

如果您感到好奇,可以通过打开标准文本编辑器中应用程序数据目录中首选项管理器创建的首选项文件来仔细检查。

答案 1 :(得分:-1)

onResume你必须获得对SharedPreferences的新参考,否则你只是使用已经在内存中的对象(并且具有旧值)

编辑: 而不是你不理解的低调投票,为什么不要求澄清呢? 我的意思是你应该以正确的方式拉你的Prefs(而不是你怎么做)......

 SharedPreferences sp = getSharedPreferences(getPackageName(), MODE_PRIVATE);

然后看看会发生什么。