Intereting Posts

OnSharedPreferenceChanged не активируется, если изменения происходят в отдельной активности?

Я реализовал onSharedPreferenceChanged в своей основной деятельности.

Если я изменю предпочтения в основной деятельности, мое событие срабатывает.

Если я изменил настройки на экране настроек ( PreferenceActivity ), мое событие НЕ запускается при изменении настроек (поскольку это отдельное действие и отдельная ссылка на sharedPreferences?)

У кого-нибудь есть рекомендация о том, как мне следует преодолевать эту ситуацию?

Благодаря!

EDIT1: Я попытался добавить обработчик событий прямо в свою активность, но он никогда не срабатывает. Следующий метод вызывается во время onCreate моей активности предпочтений. Когда я изменяю значения, он никогда не печатает сообщение ( msg() является оберткой для Log.d ).

 private void registerChangeListener () { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); sp.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener () { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { msg (" ***** Shared Preference Update ***** "); Intent i = new Intent(); i.putExtra("KEY", key); i.setAction("com.gtosoft.dash.settingschanged"); sendBroadcast(i); // TODO: fire off the event } }); } 

Solutions Collecting From Web of "OnSharedPreferenceChanged не активируется, если изменения происходят в отдельной активности?"

OnSharedPreferenceChangeListener получает мусор, собранный в вашем случае, если вы используете анонимный класс.

Чтобы решить эту проблему, используйте следующий код в PreferenceActivity для регистрации и отмены регистрации прослушивателя изменений:

 public class MyActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { @Override protected void onResume() { super.onResume(); // Set up a listener whenever a key changes getPreferenceScreen().getSharedPreferences() .registerOnSharedPreferenceChangeListener(this); } @Override protected void onPause() { super.onPause(); // Unregister the listener whenever a key changes getPreferenceScreen().getSharedPreferences() .unregisterOnSharedPreferenceChangeListener(this); } public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) { // do stuff } 

Кроме того, имейте в виду, что прослушиватель только вызывается, если изменяется фактическое значение. Повторное включение одинакового значения не приведет к срабатыванию слушателя.

См. Также SharedPreferences.onSharedPreferenceChangeListener не вызывается последовательно

Это происходит потому, что сборщик мусора. Его работы только один раз. То ссылка собирается как мусор. Поэтому создайте поле экземпляра для слушателя.

 private OnSharedPreferenceChangeListener listner; listner = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { //implementation goes here } }; prefs.registerOnSharedPreferenceChangeListener(listner); 

Я приехал сюда, как и многие другие, потому что мой слушатель не будет уволен, когда я изменил свое логическое значение с true на false или наоборот.

После многого чтения и рефакторинга, переключения contexts/inner classes/privates/static/ и т. П., Я осознал свою (тупую) ошибку:

onSharedPreferenceChanged только вызывается, если что-то меняется. Только. Когда-либо.

Во время моих тестов я был настолько тупым, чтобы постоянно нажимать на одну и ту же кнопку, тем самым все время добавляя одинаковое логическое значение в предпочтение, поэтому оно никогда не менялось.

Надеюсь, это поможет кому-то!

Еще один способ избежать проблемы – сделать вашу деятельность классом слушателя. Поскольку существует только один метод переопределения с отличительным именем, вы можете сделать это:

 public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sharedPreferences.registerOnSharedPreferenceChangeListener(this); ... } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { ... } } 

Обратите внимание, что в оригинальном вопросе речь шла о прослушивании MainActivity для изменения настроек в PreferenceActivity. Затем искатель добавил «EDIT1» и изменил вопрос на прослушивание в самой PreferenceActivity. Это проще, чем первое, и, похоже, это то, что все ответы предполагают. Но что, если вы все еще хотите использовать прежний сценарий?

Ну, это тоже сработает, но не используйте OnResume () и OnPause () для регистрации и отмены регистрации слушателя. Это приведет к тому, что слушатель окажется неэффективным, потому что пользователь покидает MainActivity, когда использует PreferenceActivity (что имеет смысл, когда вы думаете об этом). Так что это сработает, но ваша MainActivity все равно будет прослушиваться в фоновом режиме, даже если пользователь не использует его. Вид траты ресурсов не так ли? Итак, есть другое решение, которое, кажется, работает, просто добавьте метод OnResume (), чтобы перечитать все настройки. Таким образом, когда пользователь заканчивает редактирование предпочтений в PreferenceActivity, MainActivity заберет их, когда пользователь вернется к нему, и вам вообще не нужен прослушиватель .

Кто-то, пожалуйста, сообщите мне, если они видят проблему с этим подходом.

Читая читаемые Word данные, разделяемые первым приложением, мы должны

замещать

 getSharedPreferences("PREF_NAME", Context.MODE_PRIVATE); 

с

 getSharedPreferences("PREF_NAME", Context.MODE_MULTI_PROCESS); 

Во втором приложении, чтобы получить обновленное значение во втором приложении.

Почему бы вам просто не добавить onSharedPreferenceChanged в остальные действия, в которых предпочтения могут измениться?

Сборщик мусора стирает, что … вам следует использовать вместо него контекст приложения … или просто добавить код при запуске приложения … а затем добавить слушателя в контекст приложения …