在PreferenceActivity中,findPreference()抛出了NullPointerException(Android)。
在PreferenceActivity中,findPreference()抛出了NullPointerException(Android)。
我使用了Kevin Remo在这里给出的答案创建了自己的自定义PreferenceActivity
。这段代码没有onPreferenceClickListener
,所以我在我的活动的onResume
中添加了它。它在API 9上工作得很好,但在API 19上失败了。
以下是我的活动代码。
import android.content.Context; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.util.AttributeSet; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Toast; public class SettingsActivity extends CompatiblePreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { setPrefs(R.xml.user_settings); super.onCreate(savedInstanceState); } @Override public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { // TODO Auto-generated method stub return super.onCreateView(parent, name, context, attrs); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Preference logout = (Preference) findPreference("preflogout"); logout.setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { Toast.makeText(getApplicationContext(), preference.getKey(), Toast.LENGTH_LONG).show(); return false; // 在这里打开浏览器或意图 } }); CheckBoxPreference notification = (CheckBoxPreference) findPreference("prefpushnotification"); notification .setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { CheckBoxPreference notification1 = (CheckBoxPreference) preference; if (notification1.isChecked()) { notification1.setSummary("通知已开启"); } else { notification1.setSummary("通知已关闭"); } return false; // 在这里打开浏览器或意图 } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // 填充菜单;如果存在,则将项目添加到操作栏中。 getMenuInflater().inflate(R.menu.user_setting, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // 在这里处理操作栏项目的单击事件。操作栏将自动处理对主页/上一个按钮的单击,只要您在AndroidManifest.xml中指定了父活动。 int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
在onResume
中,我使用了findPreference()
,在API 19上会出现NPE,但在API 9上工作正常。
这是我使用的支持2x到4x版本的自定义首选项活动类,正如链接中回答中所说。
import android.annotation.TargetApi; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; public class CompatiblePreferenceActivity extends PreferenceActivity { private int prefs = 0; // 获取/设置首选项 public void setPrefs(int prefs) { this.prefs = prefs; } // 异常类 protected static class PrefsNotSetException extends RuntimeException { private static final long serialVersionUID = 1L; PrefsNotSetException() { super("\"prefs\"应设置为有效的首选项资源ID。"); } } // 创建 @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (prefs == 0) throw new PrefsNotSetException(); else try { getClass().getMethod("getFragmentManager"); AddResourceApi11AndGreater(); } catch (NoSuchMethodException e) { // Api < 11 AddResourceApiLessThan11(); } } @SuppressWarnings("deprecation") protected void AddResourceApiLessThan11() { addPreferencesFromResource(prefs); } @TargetApi(11) protected void AddResourceApi11AndGreater() { PF.prefs = prefs; getFragmentManager().beginTransaction() .replace(android.R.id.content, new PF()).commit(); } @TargetApi(11) public static class PF extends PreferenceFragment { private static int prefs; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(prefs); } } // 修复子屏幕背景故障 @SuppressWarnings("deprecation") @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { super.onPreferenceTreeClick(preferenceScreen, preference); if (preference != null) if (preference instanceof PreferenceScreen) if (((PreferenceScreen) preference).getDialog() != null) ((PreferenceScreen) preference) .getDialog() .getWindow() .getDecorView() .setBackgroundDrawable( this.getWindow().getDecorView() .getBackground().getConstantState() .newDrawable()); return false; } }
堆栈跟踪:
02-13 19:54:08.222: E/AndroidRuntime(4282): java.lang.RuntimeException: Unable to resume activity {com.buzzreel/com.buzzreel.SettingsActivity}: java.lang.NullPointerException 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2774) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.ActivityThread.access$800(ActivityThread.java:135) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.os.Handler.dispatchMessage(Handler.java:102) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.os.Looper.loop(Looper.java:136) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.ActivityThread.main(ActivityThread.java:5001) 02-13 19:54:08.222: E/AndroidRuntime(4282): at java.lang.reflect.Method.invokeNative(Native Method) 02-13 19:54:08.222: E/AndroidRuntime(4282): at java.lang.reflect.Method.invoke(Method.java:515) 02-13 19:54:08.222: E/AndroidRuntime(4282): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 02-13 19:54:08.222: E/AndroidRuntime(4282): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 02-13 19:54:08.222: E/AndroidRuntime(4282): at dalvik.system.NativeStart.main(Native Method) 02-13 19:54:08.222: E/AndroidRuntime(4282): Caused by: java.lang.NullPointerException 02-13 19:54:08.222: E/AndroidRuntime(4282): at com.buzzreel.SettingsActivity.onResume(SettingsActivity.java:42) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192) 02-13 19:54:08.222: E/AndroidRuntime(4282): at android.app.Activity.performResume(Activity.java:5310)