Search code examples
androidpreferences

Android SharedPreferences from PreferenceActivity


I have a PreferenceActivity that loads its preferences from an XML file which looks like this

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="first_preferencescreen">
   <ListPreference
 android:key="currlist"
    android:title="Change Currency"
    android:summary="Selecting a new currency will reset your jar!"
    android:entries="@array/currencies"
    android:entryValues="@array/currency_vals" />
    <EditTextPreference
    android:key="goaltxt"
    android:title="Set Goal"
    android:inputType="numberDecimal"
    android:text="0.00"
    />
</PreferenceScreen>

I want to pass both the currency type and the goal back to the main class, and all the explanations I've found are very vague. In my onStart() method in my main class I have this so far:

public void onStart() {
  SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
  SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
  final SharedPreferences.Editor prefsEditor = myPrefs.edit();

  prefs.getInt("currlist", 0);
  prefs.getFloat("goaltxt", 0);


 }

This is really frustrating, and I'd love some insight on how SharedPreferences works. Thanks!


Solution

  • SharedPreferences are a way of sharing data between many parts of your application. Once someone has a reference to a shared preference they can read things from it like so:

    int currlist = prefs.getInt("currlist", 0);
    float goal   = prefs.getFloat("goaltxt", 0);
    

    They can also register to receive notifications that the data has changed:

    prefs.registerOnSharedPreferenceChangeListener(this);
    

    Their onSharedPreferenceChanged method will fire when someone changes the data in the shared preferences (they must implement the SharedPreferenceChangedListener interface of course). Remember to unregister once you're no longer observing the data set.

    How does it know when the preferences have changed? Well, you must get a reference to a SharedPreferences.Editor before you can edit the data inside the SharedPreferences, like you have done:

    final SharedPreferences.Editor prefsEditor = prefs.edit();
    

    At this point you use the editor to add or update some variable stored in the shared preferences:

    prefsEditor.putInt("currlist", 1);
    

    And when you're done editing you commit your changes, this will notify all the listeners that a change has happened:

    prefsEditor.commit();
    

    At this point, all the registered observers will be notified that there has been a change to the shared preferences (including your own!)

    How to put this to use:

    1. When your application, activity, service or whatever starts, grab a reference to the shared preference you're interested in, copy all the values you need into class member variables and register yourself as an observer.

    2. Remember to remove the listener when your class is no longer active and/or listening to change events.

    3. In your onSharedPreferenceChanged method, check to see if the value in prefs.getWhatever("value", default) is different from your class member variable. If it is, take action but be aware that this is probably being called from another thread; you can't edit the UI from outside a UI thread or things will crash, similarly you don't want to cause delays on the UI thread or it will hang. Do very fast, local work only (add stuff to queues etc) and be sure to write threadsafe code.

    4. When you change some value which is shared, first change your class member variable, then grab a prefs editor, make the change to the variable and commit() the result. Your local onSharedPreferenceChanged listener will fire, but as the value is the same as your member variable you will ignore it.

    From this point on your inter-class communication is solid, make a change to the prefs and the UI seamlessly updates, send an update to running services, pass values around between unrelated activities.