如何正确应用onPreferenceChangeListener?

时间:2015-03-18 03:02:41

标签: android

在修改设置活动的Udacity Android development video中,我按照this gist实施了代码,但在Android Monitor上收到错误

  

03-18 10:52:59.625:E / AndroidRuntime(2520):java.lang.RuntimeException:无法启动活动ComponentInfo {com.example.android.sunshine / com.example.android.sunshine.SettingsActivity}: java.lang.NullPointerException:尝试在空对象引用上调用虚方法'void android.preference.Preference.setOnPreferenceChangeListener(android.preference.Preference $ OnPreferenceChangeListener)'

相关代码是

   private void bindPreferenceSummaryToValue(Preference preference) {
    // Set the listener to watch for value changes.
    preference.setOnPreferenceChangeListener(this);

    // Trigger the listener immediately with the preference's
    // current value.
    onPreferenceChange(preference,
            PreferenceManager
                    .getDefaultSharedPreferences(preference.getContext())
                    .getString(preference.getKey(), ""));
}

所以看起来this未定义,是吗?

3 个答案:

答案 0 :(得分:5)

在这种情况下,传递的preference为null。 真正的罪魁祸首可能是您编写引用的XML布局文件中的缺少条目。

找到它的简单方法是查看堆栈跟踪,并从SettingsActivity或其中引用它的某个Activity中查看它所要调用的字段。 例如:

bindPreferenceSummaryToValue(findPreference("mytypes"));

查看上述案例中的enabled是否正在添加到您的布局中:

<ListPreference
   android:entries="@array/pref_my_types"
   android:entryValues="@array/pref_my_values"
   android:key="mytypes"
   android:title="MyTypes"/>

如果缺少此项,则会抛出NPEfindPreference("mytypes")将返回null。

答案 1 :(得分:0)

认为您的Preference对象更有可能为null。在这种情况下,&#39;这个&#39;指的是运行bindPreferenceSummaryToValue(Preference)的Activity,因此它不能为null。设置一个断点到该行:

preference.setOnPreferenceChangeListener(this);

并且您将能够确定在运行debug时确定哪个为null。

答案 2 :(得分:0)

EditTextPreference中的键应与bindPreferenceSummaryToValue中的键匹配。

   <EditTextPreference
       android:key="@string/pref_location_key"
       android:title="@string/pref_location_label"
       android:defaultValue="@string/pref_default_display_name"
       android:selectAllOnFocus="true"
       android:inputType="textCapWords"
       android:capitalize="words"
       android:singleLine="true"
       android:maxLines="1" /> 

和我在bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));传递的密钥 Android:键值和bindPreferenceSummaryToValue应指向相同。