Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de0c99e8 authored by Andrew Solovay's avatar Andrew Solovay
Browse files

Noted that OnSharedPreferenceChangeListener does not store a strong reference

to the listener.

Because of this, the listener is susceptible to garbage collection unless the
caller preserves a strong reference to it. We suggest that the caller store a
reference to the listener in an instance field of an object that will exist as
long as the listener is needed.

Also fixed code sample formatting in Settings.jd (some lines were overlong).

Docs are staged in:

http://asolovay.mtv:8901/guide/topics/ui/settings.html#Listening

http://asolovay.mtv:8901/reference/android/content/SharedPreferences.html#registerOnSharedPreferenceChangeListener(android.content.SharedPreferences.OnSharedPreferenceChangeListener)

Bug: 10437648
Change-Id: I48f5b87fa2ca7a240661d0cc00114d225819d54d
parent 0e286ab1
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -356,6 +356,13 @@ public interface SharedPreferences {
    /**
     * Registers a callback to be invoked when a change happens to a preference.
     *
     * <p class="caution"><strong>Caution:</strong> The preference manager does
     * not currently store a strong reference to the listener. You must store a
     * strong reference to the listener, or it will be susceptible to garbage
     * collection. We recommend you keep a reference to the listener in the
     * instance data of an object that will exist as long as you need the
     * listener.</p>
     *
     * @param listener The callback that will run.
     * @see #unregisterOnSharedPreferenceChangeListener
     */
+39 −3
Original line number Diff line number Diff line
@@ -820,7 +820,8 @@ public class SettingsActivity extends PreferenceActivity
    public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
    ...

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
        String key) {
        if (key.equals(KEY_PREF_SYNC_CONN)) {
            Preference connectionPref = findPreference(key);
            // Set summary to be the user-description for the selected value
@@ -863,7 +864,40 @@ protected void onPause() {
}
</pre>

<p class="caution"><strong>Caution:</strong> When you call {@link
android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
registerOnSharedPreferenceChangeListener()}, the preference manager does not
currently store a strong reference to the listener. You must store a strong
reference to the listener, or it will be susceptible to garbage collection. We
recommend you keep a reference to the listener in the instance data of an object
that will exist as long as you need the listener.</p>

<p>For example, in the following code, the caller does not keep a reference to
the listener. As a result, the listener will be subject to garbage collection,
and it will fail at some indeterminate time in the future:</p>

<pre>
prefs.registerOnSharedPreferenceChangeListener(
  // Bad! The listener is subject to garbage collection!
  new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // listener implementation
  }
});
</pre>

<p>Instead, store a reference to the listener in an instance data field of an
object that will exist as long as the listener is needed:</p>

<pre>
SharedPreferences.OnSharedPreferenceChangeListener listener =
    new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // listener implementation
  }
};
prefs.registerOnSharedPreferenceChangeListener(listener);
</pre>

<h2 id="NetworkUsage">Managing Network Usage</h2>

@@ -1142,13 +1176,15 @@ protected Parcelable onSaveInstanceState() {
    final Parcelable superState = super.onSaveInstanceState();
    // Check whether this Preference is persistent (continually saved)
    if (isPersistent()) {
        // No need to save instance state since it's persistent, use superclass state
        // No need to save instance state since it's persistent,
        // use superclass state
        return superState;
    }

    // Create instance of custom BaseSavedState
    final SavedState myState = new SavedState(superState);
    // Set the state's value with the class member that holds current setting value
    // Set the state's value with the class member that holds current
    // setting value
    myState.value = mNewValue;
    return myState;
}