ObjectInputStream.readObject()NotSerializableException

时间:2017-12-01 20:14:44

标签: java android

在Android应用中使用ObjectOutputStream和ObjectInputStream保存和读取保存在文件中的对象时遇到了一些问题 我有两个类Workout和Exercise,Workout包含一个练习列表。这两个类都实现了Serializable。这是实际的代码:

锻炼

package com.mycompany.myapp;

public class Workout implements Serializable{

private String _name;
protected ArrayList<Exercise> _list = new ArrayList<Exercise>();
private static final long serialVersionUID = 1L;
private File _fileSave;
final Context context = MyApp.getContext();

Workout(){
    _name = "Empty";
    _list = null;
 }

 Workout(String n, ArrayList<Exercise> e){
     _name = n;
     _list.addAll(e);
 }

 Workout(File fs){
     ObjectInputStream ois;
     _fileSave = fs;
     try{
         ois = new ObjectInputStream(new FileInputStream(fs));
         Workout n = (Workout) ois.readObject();   //here it fails and throws the exception
         ois.close();
         _name = n._name;
         _list = n._list;
     }catch(IOException e){ 
        e.getCause();
     }catch(ClassNotFoundException e) {
     }
 }

 protected void save(){                                 
    ObjectOutputStream oos;
    _fileSave = new File(context.getFilesDir(), _name + ".w");
    try{
        oos = new ObjectOutputStream(new FileOutputStream(_fileSave));
        oos.writeObject(this);
        oos.close();
    }
    catch(Exception e){
        e.getCause();
    }
 }
 ...

运动

public class Exercise implements Serializable{

protected String _name;
protected int _weight;
protected int _reps;
protected int _sets;
protected int _pause;
protected int _duration;
private static final long serialVersionUID = 1L;

Exercise(){
    _name = "New Empty Exercise";
    _weight = 0;
    _reps = 0;
    _sets = 0;
    _pause = 0;
}

Exercise(String n, int w, int r, int s, int d, int p){
    _name = n;
    _weight = w;
    _reps = r;
    _sets = s;
    _duration = d;
    _pause = p;
}

}

保存类的当前实例没有问题,但是当我尝试读回对象时,抛出NotSerializableException。以下是详细信息和回溯:

cause = java.io.NotSerializableException: com.mycompany.myapp.MyApp

backtrace = { long[44]@b77201, class java.io.ObjectInputStream, class java.io.ObjectInputStream, class java.io.ObjectInputStream, class java.io.ObjectInputStream, class java.io.ObjectInputStream, class java.io.ObjectInputStream, class com.mycompany.myapp.Workout$0$debug, class com.mycompany.myapp.Workout, class com.mycompany.myapp.Menu$0$debug, class com.mycompany.myapp.Menu, class android.app.Activity, class android.app.Instrumentation, class android.app.ActivityThread, class android.app.ActivityThread, class android.app.ActivityThread, class android.app.ActivityThread$H, class android.os.Handler, class android.os.Looper, class android.app.ActivityThread, class java.lang.reflect.Method, class com.android.internal.os.Zygote$MethodAndArgsCaller, class com.android.internal.os.ZygoteInit }

我无法理解我的错误或错过了什么。提前感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

对于可序列化的对象,其所有实例字段必须是可序列化的,以及它们的所有实例字段,依此类推。您的Workout有,

final Context context = MyApp.getContext();

Android的Context对象不可序列化。如果您的情况,因为您显然只是将上下文存储在静态字段中,只需删除它的实例字段并直接在您需要的地方使用MyApp.getContent()。不是我宽恕使用全局变量。

或者,正如@Bedla在评论中指出的那样,

transient final Context context = MyApp.getContext();

您也可以使用transient标记字段,表示不应序列化。但是,当然,您必须准备才能对该字段进行反序列化。