Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preference On Change Listener

I have read this helpful post :

SharedPreferences.onSharedPreferenceChangeListener not being called consistently

However I am having no luck. I am trying to create an OnSharedPreferenceChangeListener that runs in a service. Everything is implemented correctly but the listener is not always triggered.

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);
    }
}

UPDATE

The problem stems from a fact I did not mention. I am running two services and when shared preference changes are made in MyService2 nothing is triggered. In the manifest I define the services to run in different processes. Is there a way to make this work?

like image 356
jjNford Avatar asked Nov 01 '11 14:11

jjNford


1 Answers

After gaining some experience with Android I have come back to answer this question and help anyone else who is having trouble with this type of situation.

The implementation of the OnSharedPreferenceChangeListener is correct. The problem lies in the manifest and application architecture. Because the services are running in different processes Android has created difference Dalvik Virtual Machines for each service therefore they do not "hear" each others listeners.

This was just bad design - The better way to approach the idea of running two concurrent services is to create one service that threads each "service" off to run concurrently. This way they can share the same Heap thus sharing the same Objects & Listeners

If someone were determined to use two services they could create a BroadcastReceiver to catch intents for that preferences need to be changed - or communicate through sockets. There are also ways to do this with a ContentProvider (Please NEVER DO THIS). But again, there is no reason for any of this if the design is good.

like image 179
jjNford Avatar answered Oct 03 '22 20:10

jjNford