我有以下功能:
@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);
}
}
}
在对PreferenceFragment
进行更改时调用该函数。如果Hud
,服务shouldStart == false
(可能)正在运行,然后我想停止它。如果您只是单击选项两次,这将按预期工作;服务开始,然后停止。但是,如果您启动它,请返回上一个activity
,然后再次输入此fragment
,并尝试禁用它,发生以下情况:
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)
第35行是Intent intent = new Intent(getActivity(), HUD.class);
。
这里发生了什么?
答案 0 :(得分:1)
调试一段时间后我发现了问题:
getActivity()
返回null(就像Ryan所说:)。
我使用的解决方案是从this answer到类似的问题。
private Activity activity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.activity = activity;
}
并将getActivity()
替换为activity
。不是很漂亮,它可能容易出错,但它确实有效。
答案 1 :(得分:1)
您注册了您的首选项侦听器,但随后您的片段已分离,当您返回活动时,将创建一个新的。
您的旧片段实例仍然存在,由首选项作为监听器保存。
当您将片段从活动中分离时,您需要做的是取消注册片段作为首选项侦听器,并在再次连接时再次注册它。这样可以确保您的片段具有有效的活动参考。
答案 2 :(得分:0)
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);
}
}
}