【问题标题】:App crashing whenever trying to save SharedPreferences每当尝试保存 SharedPreferences 时应用程序崩溃
【发布时间】:2018-10-06 13:41:29
【问题描述】:

我有一个可以正常工作的应用程序,直到我按下两个按钮之一,这两个按钮都保存了我当前的自定义类,该类将四个 ArrayList<String> 存储为 JSON 文件。

以下是我将 JSON 文件加载到 SharedPreferences 并将其保存到 SharedPreferences 的代码:

@Override
protected void onResume() {
    super.onResume();
    SharedPreferences myPrefs = getPreferences(MODE_PRIVATE);
    Gson gson = new Gson();
    String json = myPrefs.getString("MyObject", "");
    StudentArray obj = gson.fromJson(json, StudentArray.class);

    studentsFirstNames = obj.studentFirstName;
    studentsLastNames = obj.studentLastName;
    studentsCourses = obj.studentCourse;
    studentsYearsOfStudy = obj.studentYearOfStudy;
}

@Override
protected void onPause() {
    super.onPause();
    SharedPreferences myPrefs = getPreferences(MODE_PRIVATE);
    Editor prefsEditor = myPrefs.edit();
    Gson gson = new Gson();
    StudentArray example = new StudentArray(studentsFirstNames, studentsLastNames, studentsCourses, studentsYearsOfStudy);
    String json = gson.toJson(example);
    prefsEditor.putString("MyObject", json);
    prefsEditor.commit();
}       

Logcat 崩溃日志

04-26 21:58:38.985 14971-14971/com.adam_smedley.moduleenrollment E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.adam_smedley.moduleenrollment, PID: 14971
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=0, data=null} to activity {com.adam_smedley.moduleenrollment/com.adam_smedley.moduleenrollment.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4089)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4132)
    at android.app.ActivityThread.-wrap20(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1533)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6119)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
 Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
    at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:344)
    at android.widget.ListView.setAdapter(ListView.java:493)
    at com.adam_smedley.moduleenrollment.MainActivity.onActivityResult(MainActivity.java:89)
    at android.app.Activity.dispatchActivityResult(Activity.java:6932)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4085)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4132) 
    at android.app.ActivityThread.-wrap20(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1533) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6119) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

好吧,看来我的 ArrayList 是空对象引用,因为我无法向它们添加另一个字符串或获取 .size()

任何人都可以看到下面的声明有任何问题

static ArrayList<String> studentsFirstNames;
studentsFirstNames = new ArrayList<String>();
studentsFirstNames.add("John");

在我的 AddNewStudent 活动中调用

    MainActivity.studentsFirstNames.add(firstName);   

它应该访问 Main Activity 中的静态 ArrayList studentsFirstNames 并将单个字符串 firstName 添加到 ArrayList。

onActivityResult 代码

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    ListAdapter enrollmentAdapter = new CustomAdapter(this, studentsFirstNames, studentsLastNames, studentsCourses, studentsYearsOfStudy);
    ListView studentsListView = (ListView) findViewById(R.id.StudentsListView);
    studentsListView.setAdapter(enrollmentAdapter);
}

这肯定是由上面的 onResume() 和 onPause() 代码引起的,因为我已经将其注释掉并且我的应用程序可以运行,但它没有保存任何内容,因此我没有任何数据持久性。

【问题讨论】:

  • 如果你不介意的话,你能不能只在你完成注册和保存注册时发布涉及的代码。只需编辑问题。否则你可能永远得不到任何帮助。
  • 你的inActivityResult代码在哪里,就是崩溃的地方,能分享一下吗?
  • @MidasLefko onActivityResult 代码?
  • 您不应从另一个 Activity 访问 studentsFirstNames。您需要处理onActivityResult 中的addAddNewStudent activity 肯定不知道 MainActivity 在做什么。
  • 根据堆栈跟踪,以下列表之一在 onActivityResult 中为空:studentsFirstNames、studentsLastNames、studentCourses、studentYearsOfStudy。您应该调试以找出原因和原因

标签: android json android-sharedpreferences gson


【解决方案1】:

您的onResume 方法中的StudentArray 可能无效。因此,当您使用 gson 获取对象时,您需要检查 null 或异常。像这样的:

@Override
protected void onResume() {
  super.onResume();
  SharedPreferences myPrefs = getPreferences(MODE_PRIVATE);
  Gson gson = new Gson();
  String json = myPrefs.getString("MyObject", "");
  try {
    StudentArray obj = gson.fromJson(json, StudentArray.class);
    if (obj != null) {
      studentsFirstNames = obj.studentFirstName;
      studentsLastNames = obj.studentLastName;
      studentsCourses = obj.studentCourse;
      studentsYearsOfStudy = obj.studentYearOfStudy;
    } else {
      // obj is null. You need to do something here.
    }
  } catch (IllegalStateException | JsonSyntaxException exception) {
    // there is something wrong when parsing the json
    // do something
  }
}

【讨论】:

  • 我相信是这样的。在 Logcat 中,尝试在空对象引用上获取“int java.util.List.size()”时出现致命异常。我自己没有任何 .size() 调用,所以当其他活动完成时,它是由 onResume 函数完成的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
相关资源
最近更新 更多