Когато използвате нишка/задача в рамките на услуга за android, която имплементира интерфейса OnSharedPreferenceChangeListener, промените, направени в екрана с предпочитания, не се отразяват обратно към обекта нишка/задача в услугата android.
Искам да постигна две неща:
Данните за SharedPreference трябва да бъдат заредени, когато MyTask е конструиран и инициализиран.
Когато настъпи промяна на предпочитанията, обектът 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 е член на поле от тип boolean в MyTask, който трябва да бъде зададен, когато предпочитанието "preference_name_here" се промени.
getDefaultSharedPreferences
, освен ако наистина ви трябва файл - person Mr_and_Mrs_D   schedule 13.12.2013