Sba
Sba

Reputation: 35

ObjectInputStream.readObject() NotSerializableException

I've got some problems saving and reading objects saved on a file with ObjectOutputStream and ObjectInputStream in my Android app I have two classes Workout and Exercise, Workout contains among other things a list of Exercise. Both classes implement Serializable. Here is the actual code:

Workout

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();
    }
 }
 ...

Exercise

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;
}

}

I have no problem saving current instance of the class but when I'm trying to read back the object a NotSerializableException is thrown. Here are the details and the backtrace:

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 }

I can't understand what is my mistake or what I'm missing. Thank you in advance for your help!

Upvotes: 0

Views: 204

Answers (1)

Jeffrey Blattman
Jeffrey Blattman

Reputation: 22637

For an object to be serializable, all of it's instance fields must be serializable, as well as all of their instance fields, and so on. Your Workout has,

final Context context = MyApp.getContext();

Android's Context object is not serializable. If your case, since you are apparently just storing the context in a static field, just remove the instance field for it and use MyApp.getContent() directly where you need it. Not that I condone using global variables.

Or, as pointed out by @Bedla in the comments,

transient final Context context = MyApp.getContext();

You can alternatively mark a field with transient to denote it should not be serialized. But of course, you have to be prepared for that field to not be deserialized.

Upvotes: 2

Related Questions