1

I have the following function:

@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { if (s.equals("service_enabled")) { boolean shouldStart = sharedPreferences.getBoolean(s, false); Intent intent = new Intent(getActivity(), HUD.class); if (shouldStart) { // Turn on getActivity().startService(intent); } else { // Turn off getActivity().stopService(intent); } } } 

The function is called when a change is done to my PreferenceFragment. The service Hud is (probably) running if shouldStart == false, and then I want to stop it. This works as expected if you just click the option twice; the service starts, and stops. However, if you start it, go back to the previous activity, and enter this fragment again, and try to disable it, the following happends:

01-25 22:22:44.848 32548-32548/net.hath.drawcut E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.NullPointerException at android.content.ComponentName.<init>(ComponentName.java:75) at android.content.Intent.<init>(Intent.java:3558) at net.hath.drawcut.ui.fragment.PrefsFragment.onSharedPreferenceChanged(PrefsFragment.java:35) at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java:475) at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java:385) at android.preference.Preference.tryCommit(Preference.java:1349) at android.preference.Preference.persistBoolean(Preference.java:1615) at android.preference.TwoStatePreference.setChecked(TwoStatePreference.java:83) at android.preference.TwoStatePreference.onClick(TwoStatePreference.java:69) at android.preference.Preference.performClick(Preference.java:949) at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:215) at android.widget.AdapterView.performItemClick(AdapterView.java:298) at android.widget.AbsListView.performItemClick(AbsListView.java:1100) at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749) at android.widget.AbsListView$1.run(AbsListView.java:3423) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5227) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) at dalvik.system.NativeStart.main(Native Method) 

Line 35 is Intent intent = new Intent(getActivity(), HUD.class);.

What is happening here?

3
  • Please upload the complete stacktrace Commented Jan 25, 2014 at 21:36
  • You mentioned HUD is a service, is Line 35 the approach you take in starting the service? It's likely that getActivity() is null for some reason, in which case starting the service could be done like Intent intent=new Intent("com.demo.service.ServiceClass"); this.startService(intent); Commented Jan 25, 2014 at 21:52
  • That could be, but this is in a fragment, which means I don't have the start- or stopService methods; i need to use getActivity() for that. But wouldn't it be weird if getActivity() suddenly returned null, just because a service was started? Commented Jan 25, 2014 at 22:03

3 Answers 3

1

After debugging for a while I found the problem: getActivity() returned null (just like Ryan said :).

The solution I used were from this answer to a similar question.

private Activity activity; @Override public void onAttach(Activity activity) { super.onAttach(activity); this.activity = activity; } 

and replace getActivity() with activity. Not really pretty, and it probably is prone to bugs, but it works.

Sign up to request clarification or add additional context in comments.

1 Comment

please don't do that. you are leaking a whole activity here.
1

You register your preference listener, but then your fragment is detached, and when you come back to the activity a new one is created.

Your old fragment instance is still around, held by the preferences as a listener.

What you need to do is unregister your fragment as a preference listener when you detach it from the activity, and register it again when you are attached again. This way you ensure that your fragment has a valid activity reference.

Comments

0

another way:

private Context mContex; @Override public void onActivityCreated(Bundle savedInstanceState) { mContext = getActivity(); } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { if (s.equals("service_enabled")) { boolean shouldStart = sharedPreferences.getBoolean(s, false); Intent intent = new Intent(mContext, HUD.class); if (shouldStart) { // Turn on mContext.startService(intent); } else { // Turn off mContext.stopService(intent); } } 

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.