尝试将Serializable对象写入文件时出现NotSerializableException

时间:2017-11-05 21:10:41

标签: java android serialization android-7.0-nougat

我在Android上,我试图将对象列表保存到文件中,但我总是遇到这个异常: java.io.NotSerializableException:android.app.Application

我试图找到可能导致此问题的原因,但我发现只是在尝试序列化Context对象时抛出此错误但我甚至没有尝试序列化与 Application相关的任何内容上下文

DataFileManager.java

someAudio.play().then(() => someAudio.pause());

Circle.java

public class DataFileManager implements Serializable {
    public static final String FILE_NAME = "circles.dat";
    private transient final Context ctxt;
    private Set<Save> saves;
    public DataFileManager(Context ctxt) {
        this.ctxt = ctxt;
        this.saves = new HashSet<>();
        reloadSaves();
    }

    public void reloadSaves() {
        File file = file();
        if(file.exists()) {
            try (ObjectInputStream reader = new ObjectInputStream(
                    new BufferedInputStream(ctxt.openFileInput(FILE_NAME)))) {
                saves.clear();
                try {
                    while (true) {
                        Save save = (Save) reader.readObject();
                        saves.add(save);
                    }
                } catch(EOFException e) {
                } finally {
                    reader.close();
                }
            } catch (IOException | ClassNotFoundException e) {
                Log.e(e.getClass().getName(), "", e);
            }
        } else
            Log.e("load", "file does not exist");
    }

    private void save() {
        try {
            file().createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(e.getClass().getName(), "", e);
        }
        try (ObjectOutputStream writer = new ObjectOutputStream(new BufferedOutputStream(ctxt.openFileOutput(FILE_NAME, Context.MODE_PRIVATE)))) {
            Iterator<Save> iter = saves.iterator();
            while(iter.hasNext()) {
                Save save = iter.next();
                writer.writeObject(save);
            }
            writer.flush();
            writer.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.e(e.getClass().getName(), "", e);
        } catch (IOException e) {
            Log.e(e.getClass().getName(), "", e);
        }
    }


    private File file() {
        return ctxt.getFileStreamPath(FILE_NAME);
    }


    public Save save(String saveName, Set<Circle> circles) throws SaveAlreadyExistsException {
        if(exists(saveName))
            throw new SaveAlreadyExistsException();
        Save save = createSave(saveName, circles);
        if(!saves.add(save))
            throw new SaveAlreadyExistsException();
        return save;
    }

    public Save forceSave(String saveName, Set<Circle> circles) throws UnknownSaveException {
        Save save;
        if(exists(saveName))
            (save = find(saveName)).overwrite(circles);
        else {
            save = createSave(saveName, circles);
            if(!saves.add(save)) {
                saves.remove(save);
                if(!saves.add(save))
                    throw new UnknownSaveException("Couldn't add Save object to the list");
            }
            save();
        }
        return save;
    }

    private Save createSave(String name, Set<Circle> circles) {
        Save save = new Save(name);
        save.circles.addAll(circles);
        return save;
    }

    public boolean exists(String saveName) {
        return saves.stream().anyMatch(s -> s.getName().equals(saveName));
    }

    public boolean existsIgnoreCase(String saveName) {
        return saves.stream().anyMatch(s -> s.getName().equalsIgnoreCase(saveName));
    }

    public Save find(String saveName) {
        return saves.stream().filter(s -> s.getName().equals(saveName)).findFirst().orElse(null);
    }

    public List<Save> search(String query) {
        return saves.stream().filter(s -> s.getName().toLowerCase().contains(query.toLowerCase()))
                    .collect(Collectors.toList());
    }

    public Set<Save> getSaves() {
        return Collections.unmodifiableSet(saves);
    }



    public class Save implements Serializable {
        private final String      name;
        private final Set<Circle> circles;

        private Save(String name) {
            this.name = name;
            circles = new HashSet<>();
        }

        public boolean overwrite(Set<Circle> circles) {
            if (circles != null && circles.size() > 0) {
                this.circles.clear();
                this.circles.addAll(circles);
                save();
                return true;
            }
            return false;
        }

        public Set<Circle> getCircles() {
            return circles.stream().map(Circle::clone).collect(Collectors.toSet());
        }

        public String getName() {
            return name;
        }

        @Override
        public boolean equals(Object obj) {
            return obj != null && obj instanceof Save && ((Save)obj).name.equals(this.name);
        }
    }

    public static class SaveAlreadyExistsException extends UnknownSaveException {
        public SaveAlreadyExistsException() {
            super("save already exists");
        }
    }

    public static class UnknownSaveException extends Exception {
        private static final String DFLT_MSG = "An unknown error occured";

        public UnknownSaveException() {
            super(DFLT_MSG);
        }

        public UnknownSaveException(String message) {
            super(message);
        }

        public UnknownSaveException(String message, Throwable cause) {
            super(message, cause);
        }

        public UnknownSaveException(Throwable cause) {
            super(DFLT_MSG, cause);
        }
    }
}

栈跟踪

  

E / java.io.NotSerializableException:java.io.NotSerializableException:android.app.Application   at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1224)   at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1584)   at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1549)   at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1472)   at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1218)   at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1584)   at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1549)   at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1472)   at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1218)   at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)   在com.multimedia.tp3.model.files.DataFileManager.save(DataFileManager.java:77)   在com.multimedia.tp3.model.files.DataFileManager.forceSave(DataFileManager.java:116)   在com.multimedia.tp3.DrawSurface.save(DrawSurface.java:131)   在com.multimedia.tp3.MainActivity.onActivityResult(MainActivity.java:95)   在android.app.Activity.dispatchActivityResult(Activity.java:6996)   在android.app.ActivityThread.deliverResults(ActivityThread.java:4069)   在android.app.ActivityThread.handleSendResult(ActivityThread.java:4116)   在android.app.ActivityThread.-wrap20(ActivityThread.java)   在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1516)   在android.os.Handler.dispatchMessage(Handler.java:102)   在android.os.Looper.loop(Looper.java:159)   在android.app.ActivityThread.main(ActivityThread.java:6097)   at java.lang.reflect.Method.invoke(Native Method)   在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:865)   在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

1 个答案:

答案 0 :(得分:2)

  

它是DataFileManager的内部类

将其设为public static class而不是public class。现在,您的序列化对正在序列化的DataFileManager造成了窒息,因为每个Circle都有一个隐式引用,返回到创建它的外部类实例。