1

我觉得我遗漏了一些明显的东西,但搜索让我找到了几个不同的点击,所有这些都没有直接访问我的奇怪问题。

拥有一个具有主要活动和偏好活动的应用程序。添加一个“偏好”类,它简化了阅读和设置偏好。主要活动有一个选项菜单可以访问偏好活动:

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

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();
    }
}

偏好活动:

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()手动调用 - 并且认为我不需要,因为设置正在保存,我只是没有得到更新值。

我错过了什么?:) - 狐狸。

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

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

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

由于它不明显,我迷上了 Google 的 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>

这是首选项存储 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-?,这是应该的。但是,从主 Activity 上的 SharedPreferences 读取值仍然会给出V-?, 直到应用重新启动。啊,还有,我OnPreferenceChangeListnener()在PreferenceActivity中有一个,当值改变时调用。

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

4

2 回答 2

0

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

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

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

于 2012-04-14T03:11:10.643 回答
-1

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

编辑:与其否决你不理解的答案,为什么不要求澄清呢?我的意思是你应该以正确的方式拉你的首选项(而不是你如何做)......

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

然后看看会发生什么。

于 2012-04-13T21:04:54.537 回答