【发布时间】:2012-04-26 06:07:53
【问题描述】:
我觉得我遗漏了一些明显的东西,但搜索让我找到了几个不同的点击,所有这些都没有直接访问我的奇怪问题。
拥有一个包含主要活动和偏好活动的应用。添加一个“偏好”类,它简化了阅读和设置偏好。主要活动有一个选项菜单可以访问偏好活动:
Preferences 类(包括相关性,如果我不使用此类读取设置,也会发生同样的事情)。
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。这时候调用了主Activity的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-?,直到应用重新启动。啊,还有,我在 PreferenceActivity 中有一个OnPreferenceChangeListnener(),当值发生变化时会调用它。
最终编辑:显然,这是对给定活动使用命名的 android:process。 Google 地图 API 需要这样做,以允许同一应用程序中的两个单独的 MapActivity 使用不同的设置。如果将 PreferenceActivity 移动到同一个命名进程,那么上面的代码读取onResume() 中的设置会返回正确的值。
【问题讨论】:
-
仍在查看您的代码,但这里有一个更好的代码提示:使用
static final Strings 而不是字符串资源作为您的设置键。这些值不需要本地化,并且永远不应该改变。这些以及一些小的性能原因使它们成为常量的理想候选者。 -
当您将
OnPreferenceChangeListener添加到您的showSatellite偏好设置时,您会看到什么样的行为? -
@Austyn - 谢谢!我是 Java 新手,所以我确信我的代码 - 从技术上讲 - 很糟糕。 :)
-
我会考虑附加一个监听器,明天回来更新..
-
另一个技巧,而不是使用 Preferences 类的静态方法并每次都传递您的上下文,如果您要进行多次调用,为什么不保留对 PreferenceManager 的引用到静态 Preference 方法?