2014-01-25 27 views
1

我有以下功能:新的意圖(語境,類)拋出NullPointerException異常

@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,並嘗試禁用它,下面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) 

35號線是Intent intent = new Intent(getActivity(), HUD.class);

這裏發生了什麼?

+0

請上傳整個堆棧跟蹤 – Emmanuel

+0

您提到HUD是一項服務,35行是您開始服務的方式嗎?由於某種原因,getActivity()很可能是空的,在這種情況下,啓動服務可以像 那樣完成Intent intent = new Intent(「com.demo.service.ServiceClass」); this.startService(intent); – Ryan

+0

這可能是,但這是在一個片段,這意味着我沒有start-或stopService方法;我需要使用'getActivity()'。但是,如果'getActivity()'突然返回'null',這不是很奇怪,只是因爲服務已經啓動了嗎? – MartinHaTh

回答

1

經過一段時間的調試後,我發現問題: getActivity()返回null(就像Ryan說:)。

我使用的解決方案是從this answer到一個類似的問題。

private Activity activity; 

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

和替換getActivity()activity。不是很漂亮,它可能很容易出錯,但它很有效。

+0

請不要這樣做。你在這裏泄漏整個活動。 – njzk2

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); 
    } 

} 

}

1

您註冊您的喜好監聽器,但隨後你的片段被分離,而當你回來活性的新創建一個。

您的舊片段實例仍然存在,由偏好設置爲偵聽器。

您需要做的是將您的片段作爲首選偵聽器取消註冊,當您將其從活動中分離出來並在再次連接時重新註冊。這樣你可以確保你的片段有一個有效的活動引用。

相關問題