При использовании потока/задачи в службе 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();
}
}
Моя задача.класс:
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».
getDefaultSharedPreferences
, за исключением случаев, когда вам действительно нужен файл - person Mr_and_Mrs_D   schedule 13.12.2013