在實現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',除非你真的需要一個文件 –