Предпочтение при прослушивании изменений

Я прочитал этот полезный пост:

SharedPreferences.onSharedPreferenceChangeListener вызывается непоследовательно

Однако мне не повезло. Я пытаюсь создать OnSharedPreferenceChangeListener, который работает в службе. Все реализовано правильно, но не всегда срабатывает слушатель.

public MyServiceOne extends Service {

    public SharedPreferences mSharedPreferences;

    // Listener defined by anonymous inner class.
    public OnSharedPreferenceChangeListener mListener = new OnSharedPreferenceChangeListener() {        

        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            Log.d("debug", "A preference has been changed");            
        }
    };

    @Override
    public void onCreate() {            
        mSharedPreferences = getSharedPreferences(MySharedPreferences.NAME, Context.MODE_PRIVATE);
        mSharedPreferences.registerOnSharedPreferenceChangeListener(mListener);
    }

    @Override   
    public void onDestroy() {
        super.onDestroy();
        mSharedPreferences.unregisterOnSharedPreferenceChangeListener(mListener);
    }
}

ОБНОВЛЕНИЕ

Проблема проистекает из факта, о котором я не упоминал. Я использую две службы, и при изменении общих предпочтений в MyService2 ничего не запускается. В манифесте я определяю службы, которые будут запускаться в разных процессах. Есть ли способ заставить это работать?


person jjNford    schedule 01.11.2011    source источник


Ответы (3)


Получив некоторый опыт работы с Android, я вернулся, чтобы ответить на этот вопрос и помочь всем, у кого возникли проблемы с подобными ситуациями.

Реализация OnSharedPreferenceChangeListener верна. Проблема заключается в манифесте и архитектуре приложения. Поскольку службы выполняются в разных процессах, Android создал разные виртуальные машины Dalvik для каждой службы, поэтому они не «слышат» слушателей друг друга.

Это был просто плохой дизайн - лучший способ приблизиться к идее запуска двух одновременных служб - создать одну службу, которая будет выполнять параллельную работу каждой «службы». Таким образом, они могут совместно использовать одну и ту же кучу, тем самым разделяя одни и те же объекты и слушатели.

Если бы кто-то был настроен использовать две службы, он мог бы создать BroadcastReceiver, чтобы улавливать намерения для изменения этих предпочтений - или общаться через сокеты. Есть также способы сделать это с помощью ContentProvider (пожалуйста, НИКОГДА НЕ ДЕЛАЙТЕ ЭТОГО). Но, опять же, нет причин для этого, если дизайн хороший.

person jjNford    schedule 01.03.2012
comment
Вы также можете создать метод, который постоянно обновляет общий файл настроек перед получением данных или его редактированием. - person Droid Chris; 04.01.2014

Почему бы не позволить вашей службе реализовать OnSharedPreferenceChangeListener?

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

person Lars    schedule 01.11.2011
comment
Это было первое, что я попробовал, и это тоже не сработало. Извините, что не упомянул об этом. - person jjNford; 01.11.2011
comment
Единственное, о чем я могу думать, это то, что, возможно, вы вызываете неправильные SharedPreferences. Вы пробовали использовать mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());? - person Lars; 01.11.2011
comment
Да, я пробовал это, и это тоже не сработало. Я знаю, что называю это правильно, поскольку я тестировал это с тем же кодом в PreferenceActivity, который у меня есть, и он отлично работал. Однако я пытаюсь получить слушателя в службе, чтобы я мог выполнить действие в его классе. Просто кажется более логичным и легким в отслеживании и отладке. Единственное решение, которое я вижу на данный момент, - это реализовать его в PreferenceActivity и отправить широковещательную рассылку ... просто похоже, что должен быть лучший способ. - person jjNford; 01.11.2011
comment
Я просто проверяю, вызываю ли я правильные настройки, регистрируя некоторые значения, и это было правильно, так что это точно не проблема. - person jjNford; 01.11.2011
comment
Что ж, боюсь, я не знаю, из-за чего это не работает. Но я могу предложить альтернативу. Как насчет того, чтобы ваш Application класс стал OnSharedPreferenceChangedListener? Таким образом, вы также можете слушать, когда предпочтение изменено, а PreferenceActivity неактивен. - person Lars; 01.11.2011
comment
Хорошо, я нашел проблему ... проверьте обновление, потому что от него будет еще один вопрос. Спасибо. - person jjNford; 01.11.2011
comment
Извините, я мало знаю о процессах и тому подобном, и боюсь, что больше не могу вам помочь. Но желаю удачи. - person Lars; 01.11.2011

Я знаю, что эта ветка устарела. Но кто-нибудь пробовал это с помощью MODE_MULTI_PROCESS?

MODE_MULTI_PROCESS

person WoodsLink    schedule 31.08.2014