Я регистрирую слушателя изменения предпочтений следующим образом (в onCreate()
моей основной деятельности):
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
System.out.println(key);
}
});
Беда в том, что слушателя не всегда зовут. Он работает первые несколько раз, когда изменяется предпочтение, и затем он больше не вызывается, пока я не удалю и не переустановлю приложение. Никакое количество перезапуска приложения, кажется, не может это исправить.
Я нашел список рассылки нить отчетности такая же проблема, но никто не ответил ему на самом деле. Что я делаю не так?
этот принятый ответ в порядке, так как для меня это создание нового экземпляра каждый раз, когда действие возобновляется
так как насчет сохранения ссылки на слушателя в деятельности
и в вашем onResume и onPause
это будет очень похоже на то, что вы делаете, за исключением того, что мы поддерживаем жесткую ссылку.
источник
super.onResume()
раньшеgetPreferenceScreen()...
?super.onResume()
требуется или использовать его, прежде чемgetPreferenceScreen()
требуется? потому что я говорю о правильном месте. cs.dartmouth.edu/~campbell/cs65/lecture05/lecture05.htmlthis
и нетlistener
, это вызвало ошибку, и я смог решить мою проблему. Кстати, эти два метода сейчас публичны, а не защищеныПоскольку это самая подробная страница по теме, я хочу добавить свои 50 кар.
У меня была проблема, что OnSharedPreferenceChangeListener не был вызван. Мои SharedPreferences извлекаются в начале основного действия следующим образом:
Мой код PreferenceActivity короток и ничего не делает, кроме отображения настроек:
Каждый раз, когда нажимается кнопка меню, я создаю PreferenceActivity из основного Activity:
Обратите внимание, что регистрация OnSharedPreferenceChangeListener должна быть выполнена ПОСЛЕ создания в этом случае PreferenceActivity, иначе обработчик в основной операции не будет вызван !!! Мне понадобилось немного времени, чтобы понять, что ...
источник
Принятый ответ создает
SharedPreferenceChangeListener
каждый раз, когдаonResume
называется. @Samuel решает эту проблему, ставSharedPreferenceListener
членом класса Activity. Но есть третье и более простое решение, которое Google также использует в этой кодовой метке . Сделайте так, чтобы ваш класс активности реализовалOnSharedPreferenceChangeListener
интерфейс и переопределилonSharedPreferenceChanged
в Activity, эффективно делая само Activity aSharedPreferenceListener
.источник
Код Kotlin для регистра SharedPreferenceChangeListener определяет, когда произойдет изменение сохраненного ключа:
Вы можете поместить этот код в onStart () или где-то еще .. * Учтите, что вы должны использовать
или ваши коды внутри блока "// Что-то делать" будут выполняться неправильно для каждого изменения, которое будет происходить с любым другим ключом в sharedPreferences
источник
Так что я не знаю, поможет ли это кому-нибудь, хотя это решило мою проблему. Несмотря на то, что я реализовал,
OnSharedPreferenceChangeListener
как указано в принятом ответе . Тем не менее, у меня было несоответствие с вызываемым слушателем.Я пришел сюда, чтобы понять, что Android через некоторое время просто отправляет его на сборку мусора. Итак, я посмотрел на мой код. К своему стыду, я не объявил слушателя ГЛОБАЛЬНО, а вместо этого внутри
onCreateView
. И это потому, что я слушал Android Studio, в которой мне предлагалось преобразовать слушателя в локальную переменную.источник
Имеет смысл, что слушатели хранятся в WeakHashMap. Большую часть времени разработчики предпочитают писать такой код.
Это может показаться неплохим. Но если бы контейнер OnSharedPreferenceChangeListeners не был WeakHashMap, это было бы очень плохо. Если код выше был написан в Activity. Поскольку вы используете нестатический (анонимный) внутренний класс, который неявно содержит ссылку на включающий экземпляр. Это приведет к утечке памяти.
Более того, если вы сохраняете слушателя как поле, вы можете использовать registerOnSharedPreferenceChangeListener в начале и вызывать unregisterOnSharedPreferenceChangeListener в конце. Но вы не можете получить доступ к локальной переменной в методе, находящемся за ее пределами. Таким образом, у вас есть возможность зарегистрироваться, но нет возможности отменить регистрацию слушателя. Таким образом, использование WeakHashMap решит проблему. Это способ, который я рекомендую.
Если вы сделаете экземпляр слушателя как статическое поле, это позволит избежать утечки памяти, вызванной нестатическим внутренним классом. Но так как слушателей может быть несколько, это должно быть связано с экземпляром. Это уменьшит стоимость обработки обратного вызова onSharedPreferenceChanged .
источник
При чтении удобочитаемых данных Word, используемых первым приложением, мы должны
замещать
с участием
во втором приложении, чтобы получить обновленное значение во втором приложении.
Но все равно это не работает ...
источник