来自 PreferenceActivity 的 Android SharedPreferences
我有一个 PreferenceActivity,它从 XML 文件加载其首选项,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="first_preferencescreen">
<ListPreference
android:key="currlist"
android:title="Change Currency"
android:summary="Selecting a new currency will reset your jar!"
android:entries="@array/currencies"
android:entryValues="@array/currency_vals" />
<EditTextPreference
android:key="goaltxt"
android:title="Set Goal"
android:inputType="numberDecimal"
android:text="0.00"
/>
</PreferenceScreen>
我想将货币类型和目标传递回主类,而我发现的所有解释都非常模糊。到目前为止,在我的主类的 onStart() 方法中,我有这样的情况:
public void onStart() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
final SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefs.getInt("currlist", 0);
prefs.getFloat("goaltxt", 0);
}
这确实令人沮丧,我希望了解 SharedPreferences 的工作原理。谢谢!
I have a PreferenceActivity that loads its preferences from an XML file which looks like this
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="first_preferencescreen">
<ListPreference
android:key="currlist"
android:title="Change Currency"
android:summary="Selecting a new currency will reset your jar!"
android:entries="@array/currencies"
android:entryValues="@array/currency_vals" />
<EditTextPreference
android:key="goaltxt"
android:title="Set Goal"
android:inputType="numberDecimal"
android:text="0.00"
/>
</PreferenceScreen>
I want to pass both the currency type and the goal back to the main class, and all the explanations I've found are very vague. In my onStart() method in my main class I have this so far:
public void onStart() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
final SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefs.getInt("currlist", 0);
prefs.getFloat("goaltxt", 0);
}
This is really frustrating, and I'd love some insight on how SharedPreferences works. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
SharedPreferences 是一种在应用程序的许多部分之间共享数据的方法。一旦有人引用了共享首选项,他们就可以从中读取内容,如下所示:
他们还可以注册以接收数据已更改的通知:
当有人更改共享首选项中的数据时,他们的
onSharedPreferenceChanged
方法将触发共享首选项(当然,它们必须实现 SharedPreferenceChangedListener 接口)。一旦您不再观察数据集,请记住取消注册。它如何知道偏好何时发生变化?好吧,您必须先获得对 SharedPreferences.Editor 的引用,然后才能编辑 SharedPreferences 内的数据,就像您所做的那样:
此时,您使用编辑器添加或更新共享首选项中存储的某些变量:
当您完成编辑并提交更改时,这将通知所有侦听器发生了更改:
此时,所有注册的观察者都会收到通知,发生了更改更改共享首选项(包括您自己的!)
如何使用它:
当您的应用程序、活动、服务或任何内容启动时,获取对您感兴趣的共享首选项的引用,复制您的所有值需要进入类成员变量并将自己注册为观察者。
请记住,当您的类不再处于活动状态和/或侦听更改事件时,删除侦听器。
在您的
onSharedPreferenceChanged
方法中,检查prefs.getWhatever("value", default)
中的值是否与您的类成员变量不同。如果是,请采取行动但请注意这可能是从另一个线程调用的;你不能从 UI 线程外部编辑 UI,否则事情会崩溃,同样,你也不希望在 UI 线程上造成延迟,否则它会挂起。仅执行非常快速的本地工作(将内容添加到队列等),并确保编写线程安全代码。当您更改某些共享值时,首先更改您的类成员变量,然后使用首选项编辑器,对变量进行更改并
commit()
结果。您的本地onSharedPreferenceChanged
侦听器将触发,但由于该值与您的成员变量相同,您将忽略它。从这一点开始,您的类间通信是可靠的,对首选项和 UI 进行无缝更新的更改,向正在运行的服务发送更新,在不相关的活动之间传递值。
SharedPreferences are a way of sharing data between many parts of your application. Once someone has a reference to a shared preference they can read things from it like so:
They can also register to receive notifications that the data has changed:
Their
onSharedPreferenceChanged
method will fire when someone changes the data in the shared preferences (they must implement theSharedPreferenceChangedListener
interface of course). Remember to unregister once you're no longer observing the data set.How does it know when the preferences have changed? Well, you must get a reference to a
SharedPreferences.Editor
before you can edit the data inside theSharedPreferences
, like you have done:At this point you use the editor to add or update some variable stored in the shared preferences:
And when you're done editing you commit your changes, this will notify all the listeners that a change has happened:
At this point, all the registered observers will be notified that there has been a change to the shared preferences (including your own!)
How to put this to use:
When your application, activity, service or whatever starts, grab a reference to the shared preference you're interested in, copy all the values you need into class member variables and register yourself as an observer.
Remember to remove the listener when your class is no longer active and/or listening to change events.
In your
onSharedPreferenceChanged
method, check to see if the value inprefs.getWhatever("value", default)
is different from your class member variable. If it is, take action but be aware that this is probably being called from another thread; you can't edit the UI from outside a UI thread or things will crash, similarly you don't want to cause delays on the UI thread or it will hang. Do very fast, local work only (add stuff to queues etc) and be sure to write threadsafe code.When you change some value which is shared, first change your class member variable, then grab a prefs editor, make the change to the variable and
commit()
the result. Your localonSharedPreferenceChanged
listener will fire, but as the value is the same as your member variable you will ignore it.From this point on your inter-class communication is solid, make a change to the prefs and the UI seamlessly updates, send an update to running services, pass values around between unrelated activities.