Preferenceactivity#findPreference() returns null

Asked

Viewed 197 times

1

someone could help with the error below?

I’m beginner with android and could not identify where I missed.

Thank you!

Log Bug

01-22 11:45:32.722 13037-13037/com.example.android.sunshine.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.sunshine.app, PID: 13037
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.sunshine.app/com.example.android.sunshine.app.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.preference.Preference.setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2491)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2564)
at android.app.ActivityThread.access$800(ActivityThread.java:170)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1441)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5576)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:956)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:751)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.preference.Preference.setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)' on a null object reference
at com.example.android.sunshine.app.SettingsActivity.bindPreferenceSummaryToValue(SettingsActivity.java:40)
at com.example.android.sunshine.app.SettingsActivity.onCreate(SettingsActivity.java:30)
at android.app.Activity.performCreate(Activity.java:6041)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2437)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2564) 
at android.app.ActivityThread.access$800(ActivityThread.java:170) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1441) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5576) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:956) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:751) 

xml strings.

<string name="app_name">Sunshine</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="action_refresh" translatable="false">Refresh</string>
<string name="title_activity_detail">Details</string>
<string name="title_activity_settings">Settings</string>


<string name="pref_location_label" >Location</string>

<string name="pref_location_key" translatable="false">location</string>

<string name="pref_location_default" translatable="false">94043</string>

Settingsactivity.java

import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

public class SettingsActivity extends PreferenceActivity
        implements Preference.OnPreferenceChangeListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.pref_general);

        bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));
    }

    private void bindPreferenceSummaryToValue(Preference preference) {

        preference.setOnPreferenceChangeListener(this);

        onPreferenceChange(preference,
                PreferenceManager
                        .getDefaultSharedPreferences(preference.getContext())
                        .getString(preference.getKey(), ""));
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {
        String stringValue = value.toString();

        if (preference instanceof ListPreference) {
            // For list preferences, look up the correct display value in
            // the preference's 'entries' list (since they have separate labels/values).
            ListPreference listPreference = (ListPreference) preference;
            int prefIndex = listPreference.findIndexOfValue(stringValue);
            if (prefIndex >= 0) {
                preference.setSummary(listPreference.getEntries()[prefIndex]);
            }
        } else {
            // For other preferences, set the summary to the value's simple string representation.
            preference.setSummary(stringValue);
        }
        return true;
    }

}

pref_general.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    >

    <EditTextPreference
        android:key="pref_location_key"
        android:title="@string/pref_location_label"
        android:defaultValue="@string/pref_location_default"
        android:inputType="text"
        android:singleLine="true" />
</PreferenceScreen>

1 answer

0


This line of logcat

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 
'void android.preference.Preference.setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)' 
on a null object reference

indicates that the error is NullPointerException, happens on the line

preference.setOnPreferenceChangeListener(this);

and that the reason is being called the method setOnPreferenceChangeListener() in a null object(preference).

The object preference is returned by the call to the method findPreference() on the line bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));

Check whether R.string.pref_location_key corresponds to key of the Preference or replace getString(R.string.pref_location_key) for "pref_location_key":

bindPreferenceSummaryToValue(findPreference("pref_location_key"));

The use of Resources of the kind String allows centralizing the declaration of constants of type string, allowing, when necessary to change them, the change is made in a single location.
You just have to be careful to use the resource in all places where the string is used.

Thus, in the xml declaring the Preference, you must use it in the attribute android:key:

<EditTextPreference
    android:key="@string/pref_location_key"
    android:title="@string/pref_location_label"
    android:defaultValue="@string/pref_location_default"
    android:inputType="text"
    android:singleLine="true" />
  • It corresponds, I tried to make the change but the error persists.

  • No, it doesn’t match. <string name="pref_location_label" >Location</string> is of value location. The key to Preference is pref_location_key, is that value that should be used to find findPreference(). If you change the code, as I suggested, to bindPreferenceSummaryToValue(findPreference("pref_location_key")); you’ll see that it works.

  • Thanks! Now it worked, just insert @string/ in key.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.