I’m trying to implement shared preferences to be called from two different Activities. One of the preferences is a checkbox that hides or exposes a button contained in the xml layout file of one of the Activities.
This scenario is implemented using:
public class MyPreferencesActivity extends PreferenceActivity
implements OnSharedPreferenceChangeListener { ... }
Also in the MyPreferencesActivity class, I have the preference change code as follows:
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Button btnClear = (Button) findViewById(R.id.clearbuttonid);
if (prefs.getBoolean("Clear User Flag", true))
btnClear.setVisibility(View.VISIBLE);
else
btnClear.setVisibility(View.INVISIBLE);
}
The preferences class also has:
@Override
protected void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().
registerOnSharedPreferenceChangeListener(this);
}
… with onPause() similarly unregistering the listener.
As written, I didn’t quite expect this code to work because clearbuttonid is defined in a different Activity’s xml layout file. And as you might expect, I’m getting a null pointer exception in the shared preference changed code when trying to access btnClear. But the weird thing is that everything else about it works correctly (?!). That is, when I restart the app, the preference check box has been changed, and corresponding code has been executed.
The practical question is: how do I set up preferences code to support the simple goal of being able to call preferences from two different activities, and changing a variable in one of them? Many thanks.
EDIT>> Per Raju’s request, here’s the logcat:
04-27 00:26:57.989: I/onSharedPreferenceChange(537): Shared preference changed
04-27 00:26:57.989: D/AndroidRuntime(537): Shutting down VM
04-27 00:26:57.989: W/dalvikvm(537): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
04-27 00:26:58.029: E/AndroidRuntime(537): FATAL EXCEPTION: main
04-27 00:26:58.029: E/AndroidRuntime(537): java.lang.NullPointerException
04-27 00:26:58.029: E/AndroidRuntime(537): at com.xyzzy.prototype.MyPreferencesActivity.onSharedPreferenceChanged(MyPreferencesActivity.java:49)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java:455)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java:365)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.preference.Preference.tryCommit(Preference.java:1339)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.preference.Preference.persistBoolean(Preference.java:1605)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.preference.TwoStatePreference.setChecked(TwoStatePreference.java:79)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.preference.TwoStatePreference.onClick(TwoStatePreference.java:68)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.preference.Preference.performClick(Preference.java:939)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:202)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.widget.AdapterView.performItemClick(AdapterView.java:292)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.widget.AbsListView.performItemClick(AbsListView.java:1058)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2514)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.widget.AbsListView$1.run(AbsListView.java:3168)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.os.Handler.handleCallback(Handler.java:605)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.os.Handler.dispatchMessage(Handler.java:92)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.os.Looper.loop(Looper.java:137)
04-27 00:26:58.029: E/AndroidRuntime(537): at android.app.ActivityThread.main(ActivityThread.java:4424)
04-27 00:26:58.029: E/AndroidRuntime(537): at java.lang.reflect.Method.invokeNative(Native Method)
04-27 00:26:58.029: E/AndroidRuntime(537): at java.lang.reflect.Method.invoke(Method.java:511)
04-27 00:26:58.029: E/AndroidRuntime(537): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-27 00:26:58.029: E/AndroidRuntime(537): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-27 00:26:58.029: E/AndroidRuntime(537): at dalvik.system.NativeStart.main(Native Method)
04-27 00:26:58.599: I/dalvikvm(537): threadid=3: reacting to signal 3
04-27 00:26:58.618: I/dalvikvm(537): Wrote stack traces to '/data/anr/traces.txt'
If I interpreted your question (and provided code snippets) correctly, it appears as if you’re trying to ‘push’ changes made from within the
PreferenceActivityto other (potentially running?) activities. If that’s indeed the case, you’ve probably got things backwards. In stead of trying to push preference changes, you should ‘pull’ their values from within activities.In other words, don’t write code like you currently have:
As you correctly stated yourself (and empirically established), you can’t access widgets in a layout that is not part of the current
Activity, be it a ‘regular’ one orPreferenceActivity. You should treat the preferences as a central medium to persistently store data and your app’s state. The beauty is that you can access the preferences from anywhere, as long as you have aContextreference.So in stead of trying to push the change like per above, all you need to do in the
PreferenceActivityis make sure that the change is stored. With that done, you can simply toggle the visibilty ofbtnClearfrom within theActivity(orFragment) it belongs to, by requesting the stored value from the preferences:You can put this for example inside the
onCreate(...)of yourActivity, but if you need to re-evaluate the visibility in anActivitythat might already be created and on the stack, you can simply move it to e.g.onResume().