使用 PreferenceFragment 时从 Volley 获取空指针错误

Getting null pointer error from Volley while using PreferenceFragment

我正在尝试制作一个用户可以登录并将其用户数据保存到 mysql-db 的应用程序。 我正在使用 PreferenceActivity 和 PreferenceFragment 来处理这个问题。通常这工作正常,直到我更改用户...

现在当用户 A 注销和用户 B 登录时发生错误。(共享首选项在注销时使用 clear() 和 commit() 清除..)

应用程序停止于

java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getCacheDir()'
on a null object reference
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java: 43)
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java: 78)
at com.jamp.jamp.UserProfileSettingsFragment.onSharedPreferenceChanged(UserProfileSettingsFragment.java: 171)
at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java: 479)
at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java: 387)
at android.preference.Preference.tryCommit(Preference.java: 1415)
at android.preference.Preference.persistString(Preference.java: 1448)
at android.preference.EditTextPreference.setText(EditTextPreference.java: 94)
at android.preference.EditTextPreference.onDialogClosed(EditTextPreference.java: 148)
at android.preference.DialogPreference.onDismiss(DialogPreference.java: 395)
at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java: 1337)
at android.os.Handler.dispatchMessage(Handler.java: 102)
at android.os.Looper.loop(Looper.java: 154)
at android.app.ActivityThread.main(ActivityThread.java: 6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 756)

现在这是片段的代码

package com.jamp.jamp;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;

/**
 * Created by Erikken on 05.09.2017.
 */

public class UserProfileSettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
  SessionManager session;
  SharedPreferences prefs;

  String prefs_realname;
  String prefs_email;
  String prefs_streetname;
  String prefs_postcode;
  String prefs_city;
  String prefs_state;

  @Override
  public void onCreate(final Bundle savedInstanceState) {
    prefs = this.getActivity().getSharedPreferences("JampSharedPrefs", Context.MODE_PRIVATE);
    final SharedPreferences.Editor editor = prefs.edit();
    PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);



    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.usersettings);

    session = new SessionManager(this.getActivity().getApplicationContext());


    HashMap < String, String > user = session.getUserDetails();
    final String sessionUsername = user.get(SessionManager.KEY_USERNAME);

    // ResponseListener um Request Nutzerdaten auszulesen.
    Response.Listener < String > UserDataResponseListener = new Response.Listener < String > () {
      @Override
      public void onResponse(String response) {
        try {
          JSONObject jsonResponse = new JSONObject(response);
          boolean success = jsonResponse.getBoolean("success");

          // Wenn Datenabfrage erfolgreich, JSONResponse auswerten. // If successful, import data from mysql database
          if (success) {
            String responseRealName = jsonResponse.getString("realname");
            if (responseRealName.equals("")) {
              responseRealName = getResources().getString(R.string.MissingRealName);
            }
            String responseEmail = jsonResponse.getString("email");
            if (responseEmail.equals("")) {
              responseEmail = getResources().getString(R.string.MissingEmail);
            }
            String responseStreetName = jsonResponse.getString("streetname");
            if (responseStreetName.equals("")) {
              responseStreetName = getResources().getString(R.string.MissingStreetName);
            }
            String responsePostcode = jsonResponse.getString("postcode");
            if (responsePostcode.equals("")) {
              responsePostcode = getResources().getString(R.string.MissingPostcode);
            }
            String responseCity = jsonResponse.getString("city");
            if (responseCity.equals("")) {
              responseCity = getResources().getString(R.string.MissingCity);
            }
            String responseState = jsonResponse.getString("state");
            if (responseState.equals("")) {
              responseState = getResources().getString(R.string.MissingState);
            }
            int responseAge = jsonResponse.getInt("age");
            int responseIsPremium = jsonResponse.getInt("isPremium"); // BOOLEAN

            // Add data to shared prefs
            editor.putString("realname", responseRealName);
            editor.putString("email", responseEmail);
            editor.putString("streetname", responseStreetName);
            editor.putString("postcode", responsePostcode);
            editor.putString("city", responseCity);
            editor.putString("state", responseState);
            editor.commit();

            prefs_realname = prefs.getString("realname", "");
            prefs_email = prefs.getString("email", "");
            prefs_streetname = prefs.getString("streetname", "");
            prefs_postcode = prefs.getString("postcode", "");
            prefs_city = prefs.getString("city", "");
            prefs_state = prefs.getString("state", "");

            Preference prefUserData = (Preference) findPreference("preferencescreen_userdata");
            prefUserData.setTitle(sessionUsername);
            prefUserData.setSummary(prefs_realname + "\n" +
              prefs_email + "\n" +
              prefs_streetname + "\n" +
              prefs_postcode + " " + prefs_city + "\n" +
              prefs_state);

            findPreference("settings_username").setTitle(sessionUsername);
            findPreference("settings_realname").setSummary(prefs_realname);
            findPreference("settings_email").setSummary(prefs_email);
            findPreference("settings_streetname").setSummary(prefs_streetname);
            findPreference("settings_postcode").setSummary(prefs_postcode);
            findPreference("settings_city").setSummary(prefs_city);
            findPreference("settings_state").setSummary(prefs_state);


          } else {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setMessage("Konnte Nutzerdaten nicht abrufen.")
              .setNegativeButton("Nochmal", null)
              .create()
              .show();
          }

        } catch (JSONException e) {
          e.printStackTrace();
        }

      }


    };
    // Request an userdatarequest.php senden / Send request to userdatarequest.php
    UserDataRequest userDataRequest = new UserDataRequest(sessionUsername, UserDataResponseListener);
    RequestQueue queue = Volley.newRequestQueue(this.getActivity());
    queue.add(userDataRequest);
  }

  @Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

    HashMap < String, String > user = session.getUserDetails();
    final String sessionUsername = user.get(SessionManager.KEY_USERNAME);
    final String sessionPassword = user.get(SessionManager.KEY_PASSWORD);

    Context mContext = getActivity().getApplicationContext();

    Response.Listener < String > UpdateUserDataResponseListener = new Response.Listener < String > () {

      @Override
      public void onResponse(String response) {
        try {
          JSONObject jsonResponse = new JSONObject(response);
          boolean success = jsonResponse.getBoolean("success");

          if (success) {
            Toast.makeText(getActivity().getApplicationContext(), "Change Successful", Toast.LENGTH_LONG).show();
          } else {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setMessage("Konnte Nutzerdaten nicht abrufen.")
              .setNegativeButton("Nochmal", null)
              .create()
              .show();
          }
        } catch (JSONException e) {
          e.printStackTrace();
        }
      }


    };

    if (key.equals("settings_email")) { 
      // An mySQLDB senden         
      UpdateUserDataRequest updateUserDataRequest = new UpdateUserDataRequest(sessionUsername, sessionPassword, "email", sharedPreferences.getString(key, ""), UpdateUserDataResponseListener);
      RequestQueue queue = Volley.newRequestQueue(mContext);
      queue.add(updateUserDataRequest);

      // Summary sofort erneuern. // Refresh Summaries 

      prefs_email = sharedPreferences.getString(key, "");
      findPreference(key).setSummary(prefs_email);
      findPreference("preferencescreen_userdata").setSummary(prefs_realname + "\n" +
        prefs_email + "\n" +
        prefs_streetname + "\n" +
        prefs_postcode + " " + prefs_city + "\n" +
        prefs_state);

    }

// LOTS OF SIMILAR BUTTONS FOLLOWING HERE...


  }
}

因此错误仅在重新登录用户后发生一次。 当一切似乎都已重置时它崩溃了,应用程序会重新启动,他可以根据需要随时更改他的任何数据。

我使用的 mContext 变量错了吗? 是否有一些我没有弄清楚会导致崩溃的重要值?

有什么建议吗? =/

好的,我知道了。发现其他一些有类似问题的线程。

my Context mContext = getActivity().getApplicationContext(); 在 OnPreferenceChange 方法中被调用。但这似乎还早,因为尚未调用 Fragment 中的 onCreate 方法,并且没有 activity 我的上下文应指向的位置,因此此 returns 为空。我将 mContext 变量移动到 onCreate 方法,将其从 onPreferenceChange 中删除(也进行了一些其他调整......)现在 onPreferenceChange 似乎在等待 onCreate 方法并且它完美地工作。

package com.jamp.jamp;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;

/**
 * Created by Erikken on 05.09.2017.
 */

public class UserProfileSettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener
{
    SessionManager session;
    Context mContext;

    String prefs_realname;
    String prefs_email;
    String prefs_streetname;
    String prefs_postcode;
    String prefs_city;
    String prefs_state;

    @Override
    public void onCreate(final Bundle savedInstanceState)
    {
        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
        final SharedPreferences.Editor editor = prefs.edit();
        prefs.registerOnSharedPreferenceChangeListener(this);
        mContext = getActivity().getApplicationContext();

        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.usersettings);

        session = new SessionManager(getActivity().getApplicationContext());
        session.CheckLogin();

        HashMap<String,String> user = session.getUserDetails();
        final String sessionUsername = user.get(SessionManager.KEY_USERNAME);
        final String sessionPassword = user.get(SessionManager.KEY_PASSWORD);

        // ResponseListener um Request Nutzerdaten auszulesen.
        Response.Listener<String> UserDataResponseListener = new Response.Listener<String>(){
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonResponse = new JSONObject(response);
                    boolean success = jsonResponse.getBoolean("success");

                    // Wenn Datenabfrage erfolgreich, JSONResponse auswerten. // If successful, import data from mysql database
                    if (success) {
                        String responseRealName   = jsonResponse.getString("realname");     if (responseRealName.equals(""))   {responseRealName = getResources().getString(R.string.MissingRealName);}
                        String responseEmail      = jsonResponse.getString("email");        if (responseEmail.equals(""))      {responseEmail= getResources().getString(R.string.MissingEmail);}
                        String responseStreetName = jsonResponse.getString("streetname");   if (responseStreetName.equals("")) {responseStreetName = getResources().getString(R.string.MissingStreetName);}
                        String responsePostcode   = jsonResponse.getString("postcode");     if (responsePostcode.equals(""))   {responsePostcode = getResources().getString(R.string.MissingPostcode);}
                        String responseCity       = jsonResponse.getString("city");         if (responseCity.equals(""))       {responseCity = getResources().getString(R.string.MissingCity);}
                        String responseState      = jsonResponse.getString("state");        if (responseState.equals(""))      {responseState = getResources().getString(R.string.MissingState);}
                        int    responseAge        = jsonResponse.getInt   ("age");
                        int    responseIsPremium  = jsonResponse.getInt   ("isPremium"); // BOOLEAN

                        // Add data to shared prefs
                        editor.putString("realname",responseRealName);
                        editor.putString("email",responseEmail);
                        editor.putString("streetname",responseStreetName);
                        editor.putString("postcode",responsePostcode);
                        editor.putString("city",responseCity);
                        editor.putString("state",responseState);
                        editor.commit();

                        prefs_realname = prefs.getString("realname","0");
                        prefs_email = prefs.getString("email","0");
                        prefs_streetname = prefs.getString("streetname","0");
                        prefs_postcode = prefs.getString("postcode","0");
                        prefs_city = prefs.getString("city","0");
                        prefs_state = prefs.getString("state","0");

                        Preference prefUserData = (Preference) findPreference("preferencescreen_userdata");
                        prefUserData.setTitle(sessionUsername);
                        prefUserData.setSummary(prefs_realname+"\n"
                                                +prefs_email+"\n"
                                                +prefs_streetname+"\n"
                                                +prefs_postcode + " " + prefs_city +"\n"
                                                +prefs_state);

                        findPreference("settings_username").setTitle(sessionUsername);
                        findPreference("settings_realname").setSummary(prefs_realname);
                        findPreference("settings_email").setSummary(prefs_email);
                        findPreference("settings_streetname").setSummary(prefs_streetname);
                        findPreference("settings_postcode").setSummary(prefs_postcode);
                        findPreference("settings_city").setSummary(prefs_city);
                        findPreference("settings_state").setSummary(prefs_state);


                    }else{
                        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                        builder.setMessage("Konnte Nutzerdaten nicht abrufen.")
                                .setNegativeButton("Nochmal",null)
                                .create()
                                .show();
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }


        };
        // Request an userdatarequest.php senden / Send request to userdatarequest.php
        UserDataRequest userDataRequest = new UserDataRequest(sessionUsername, UserDataResponseListener);
        RequestQueue queue = Volley.newRequestQueue(getActivity());
        queue.add(userDataRequest);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

        session = new SessionManager(mContext);
        HashMap<String,String> user = session.getUserDetails();
        final String sessionUsername = user.get(SessionManager.KEY_USERNAME);
        final String sessionPassword = user.get(SessionManager.KEY_PASSWORD);

        Response.Listener<String> UpdateUserDataResponseListener = new Response.Listener<String>(){

            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonResponse = new JSONObject(response);
                    boolean success = jsonResponse.getBoolean("success");

                    if (success){
                        Toast.makeText(mContext,"Change Successful",Toast.LENGTH_LONG).show();
                    }else{
                        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                        builder.setMessage("Konnte Nutzerdaten nicht abrufen.")
                                .setNegativeButton("Nochmal",null)
                                .create()
                                .show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }


        };

        if (key.equals("settings_email")){ // Adressenprüfung mussnoch implementiert werden.
            // An mySQLDB senden
                                                                                                  //CELLNAME                           // CELLVALUE
                     UpdateUserDataRequest updateUserDataRequest = new UpdateUserDataRequest(sessionUsername, sessionPassword, "email", sharedPreferences.getString(key, ""), UpdateUserDataResponseListener);
                     RequestQueue queue = Volley.newRequestQueue(mContext);
                     queue.add(updateUserDataRequest);
                     // Summary sofort erneuern. // Refresh Summaries instantly
                     prefs_email = sharedPreferences.getString(key, "");
                     findPreference(key).setSummary(prefs_email);
                     findPreference("preferencescreen_userdata").setSummary(prefs_realname + "\n"
                             + prefs_email + "\n"
                             + prefs_streetname + "\n"
                             + prefs_postcode + " " + prefs_city + "\n"
                             + prefs_state);

        }

        if (key.equals("settings_streetname")){
            UpdateUserDataRequest updateUserDataRequest = new UpdateUserDataRequest(sessionUsername,sessionPassword,"streetname",sharedPreferences.getString(key,""), UpdateUserDataResponseListener);
            RequestQueue queue = Volley.newRequestQueue(mContext);
            queue.add(updateUserDataRequest);
            // Summary sofort erneuern. // Refresh Summaries instantly
            prefs_streetname = sharedPreferences.getString(key,"");
            findPreference(key).setSummary(prefs_streetname);
            findPreference("preferencescreen_userdata").setSummary(prefs_realname+"\n"
                    +prefs_email+"\n"
                    +prefs_streetname+"\n"
                    +prefs_postcode + " " + prefs_city +"\n"
                    +prefs_state);
        }

        if (key.equals("settings_realname")){
            UpdateUserDataRequest updateUserDataRequest = new UpdateUserDataRequest(sessionUsername,sessionPassword,"realname",sharedPreferences.getString(key,""), UpdateUserDataResponseListener);
            RequestQueue queue = Volley.newRequestQueue(mContext);
            queue.add(updateUserDataRequest);
            // Summary sofort erneuern. // Refresh Summaries instantly
            prefs_realname = sharedPreferences.getString(key,"");
            findPreference(key).setSummary(prefs_realname);
            findPreference("preferencescreen_userdata").setSummary(prefs_realname+"\n"
                    +prefs_email+"\n"
                    +prefs_streetname+"\n"
                    +prefs_postcode + " " + prefs_city +"\n"
                    +prefs_state);
        }

        if (key.equals("settings_postcode")){
            UpdateUserDataRequest updateUserDataRequest = new UpdateUserDataRequest(sessionUsername,sessionPassword,"postcode",sharedPreferences.getString(key,""), UpdateUserDataResponseListener);
            RequestQueue queue = Volley.newRequestQueue(mContext);
            queue.add(updateUserDataRequest);
            // Summary sofort erneuern. // Refresh Summaries instantly
            prefs_postcode = sharedPreferences.getString(key,"");
            findPreference(key).setSummary(prefs_postcode);
            findPreference("preferencescreen_userdata").setSummary(prefs_realname+"\n"
                    +prefs_email+"\n"
                    +prefs_streetname+"\n"
                    +prefs_postcode + " " + prefs_city +"\n"
                    +prefs_state);
        }

        if (key.equals("settings_city")) {
            UpdateUserDataRequest updateUserDataRequest = new UpdateUserDataRequest(sessionUsername,sessionPassword,"city",sharedPreferences.getString(key,""), UpdateUserDataResponseListener);
            RequestQueue queue = Volley.newRequestQueue(mContext);
            queue.add(updateUserDataRequest);
            // Summary sofort erneuern. // Refresh Summaries instantly
            prefs_city = sharedPreferences.getString(key,"");
            findPreference(key).setSummary(prefs_city);
            findPreference("preferencescreen_userdata").setSummary(prefs_realname+"\n"
                    +prefs_email+"\n"
                    +prefs_streetname+"\n"
                    +prefs_postcode + " " + prefs_city +"\n"
                    +prefs_state);
        }
        if (key.equals("settings_state")) {
            UpdateUserDataRequest updateUserDataRequest = new UpdateUserDataRequest(sessionUsername,sessionPassword,"state",sharedPreferences.getString(key,""), UpdateUserDataResponseListener);
            RequestQueue queue = Volley.newRequestQueue(mContext);
            queue.add(updateUserDataRequest);
            // Summary sofort erneuern. // Refresh Summaries instantly
            prefs_state = sharedPreferences.getString(key,"");
            findPreference(key).setSummary(prefs_state);
            findPreference("preferencescreen_userdata").setSummary(prefs_realname+"\n"
                    +prefs_email+"\n"
                    +prefs_streetname+"\n"
                    +prefs_postcode + " " + prefs_city +"\n"
                    +prefs_state);
        }
    }
}