在实现OnSharedPreferenceChangeListener接口的android服务中使用线程/任务时,首选项屏幕中所做的更改不会反映回android服务中的线程/任务对象。OnSharedPreferenceChangeListener不能在另一个线程任务中工作
我要完成两件事情:当MyTask构造和初始化
SharedPreference数据应被加载。
当首选项更改发生时,必须使用首选项屏幕中设置的新首选项值更新MyTask对象。
问题是:偏好初始化和偏好更改不会反映到MyTask对象。
这是我的设置(仅适用于基本部分提及):
MyService.class:
public class MyService extends Sevice {
private MyTask myTask;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!serviceStarted) {
serviceStarted = true;
myTask = new MyTask(this);
Thread t = new Thread(myTask);
t.start();
}
return Service.START_STICKY;
}
@Override
public void onDestroy() {
myTask.cancel();
super.onDestroy();
}
}
MyTask.class:
public MyTask implements Runnable, OnSharedPreferenceChangeListener {
private Context mContext;
private boolean mCancelled;
public MyTask(Context context) {
mContext = context;
}
@Override
public void run() {
while(!mCancelled) {
// do something
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// FIXME: DOESN'T GET CALLED after change in preference!!!!
Log.d(TAG, "Key= " + key);
}
public void cancel() {
mCancelled = true;
}
}
preference_devices.xml :
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:key="pref_category_devices"
android:title="@string/pref_category_devices_title" >
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_devices_server"
android:title="@string/pref_devices_server_title" />
</PreferenceCategory>
</PreferenceScreen>
我试过将SharedPreferences侦听器对象编码为MyTask类的成员字段,并从提供的上下文中注册/取消注册侦听器,但那也不起作用。这些变化也没有工作:
MyTask.class(使用SharedPreference监听器类的字段成员):
public MyTask implements Runnable {
private Context mContext;
private boolean mCancelled;
private boolean mServerEnabled;
private SharedPreferences mPrefs;
private SharedPreferences.OnSharedPreferenceChangeListener
mPreferenceListener;
public MyTask(Context context) {
mContext = context;
mPrefs = mContext.getSharedPreferences("pref_category_devices",
Context.MODE_PRIVATE);
mPreferenceListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
// FIXME: DOESN'T GET CALLED after change in preference!!!!
Log.d(TAG, "Key= " + key);
}
};
mPrefs.registerOnSharedPreferenceChangeListener(mPreferenceListener);
// set the initial value of the preference setting
mServerEnabled = mPrefs.getBoolean("pref_devices_server", false);
}
@Override
public void run() {
while(!mCancelled) {
// do something
}
}
public void cancel() {
mCancelled = true;
}
}
现在我已经达到了我的扔电脑窗外的点: (
在正确的方向的任何帮助的高度赞赏:)
编辑:在代码
mPrefs = mContext.getSharedPreferences("pref_category_devices", Context.MODE_PRIVATE);
我认为第一个参数应该是首选项文件的首选项类别名称,如:“pref_category_devices”。这是不正确的!第一个参数必须是共享的首选项文件名。这并没有解决问题,但至少现在你知道不应该陷入这个陷阱。
===解决方案:===看到这条线之下Mr_and_Mrs_D +代码答案:
变化MyTask:
mPrefs = mContext.getSharedPreferences("pref_category_devices",
Context.MODE_PRIVATE);
到:
mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mPreferenceListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("preference_name_here")) {
mPrefValue = sharedPreferences.getBoolean(key, false);
// do something with boolean pref value
}
}
};
mPrefs.registerOnSharedPreferenceChangeListener(myPreferenceListener);
凡mPrefValue是MyTask中布尔类型的字段成员,当“preference_name_here”首选项更改时需要设置它。
当onDestroy被调用时,你的服务是否被取消? –
@Mr_and_Mrs_D是的,它被取消了。我在logcat日志中看到它。它逃脱了while循环。 – user504342
re:你的编辑 - 我猜对了 - 但无论如何,最好使用'getDefaultSharedPreferences',除非你真的需要一个文件 –