Search code examples
androidfile-iomarshallingparcelableparcel

Saving Parcelable data


I have a class which implements Parcelable, and could not implement Serializable because it contains some basic Android classes that I can not modify.

Some of the objects in this class are for example Location and PendingIntent (which are all conveniently Parcelable).

My problem is saving this information between the instances of my main Activity.

Currently, I'm holding a static reference to this class, which works well. But I assume that when I re-install the app, and probably when updates will come around, I won't be able to trust that this static member won't be re-initialized.

I tried to write this Parcelable to a file, but using marshall() is not always working (I'm getting Binder can't be marshalled error).

How can I safely save this information?

Thanks


Solution

  • I use a StateControl class to handle reading/writing to disc:

        public class StateControl {
    
        Context mContext;
    
        Thread worker;
        WriteObjectToFile writer;
    
        // StateControl Constructor 
        public StateControl(Context context) {
            mContext = context; 
    
            // Construct a writer to hold and save the data
            writer = new WriteObjectToFile();
    
            // Construct a worker thread to handle the writer
            worker = new Thread(writer);
    
        }// end of StateControl constructor
    
    
    
    
        // Method to save the global data
        public void saveObjectData(Object object, String key) {
    
            if (object == null){
                // I had a different action here
            } else {
    
                // Write the data to disc
                writer.setParams(new WriteParams(object, key));         
                worker.run();
    
            }
    
        }// end of saveGlobalData method
    
    
        // Method to read the Global Data
        public Object readObjectData(String key){
    
            Object returnData = (Object) readObjectFromFile(key);
    
            if (returnData == null){        
                // I had a different action here
            } else {    
                return returnData;
            }
    
        }// end of readGlobalData method
    
    
        // Method to erase the Global data
        public void clearObjectData(String key){
    
            writer.setParams(new WriteParams(null, key));       
            worker.run();
    
        }// end of clearGlobalData method   
    
        private class WriteObjectToFile implements Runnable {
    
            WriteParams params;
    
            public void setParams(WriteParams params) {
                this.params = params;
            }
    
            public void run() {         
                writeObjectToFile(params.getObject(), params.getFilename());                
            }
    
            private boolean writeObjectToFile(Object object, String filename) {
    
                boolean success = true;
    
                    ObjectOutputStream objectOut = null;
                    try {
    
                        FileOutputStream fileOut = mContext.openFileOutput(filename, Activity.MODE_PRIVATE);
                        objectOut = new ObjectOutputStream(fileOut);
                        objectOut.writeObject(object);
                        fileOut.getFD().sync();
    
                    } catch (IOException e) {
                        success = false;
                        e.printStackTrace();
                    } finally {
                        if (objectOut != null) {
                            try {
                                objectOut.close();
                            } catch (IOException e) {
                                // do nothing
                            }
    
                        }// end of if 
                    }// End of try/catch/finally block
    
                return success;
            }
    
        }// end of writeObjectToFile method
    
    
        private Object readObjectFromFile(String filename) {
    
            ObjectInputStream objectIn = null;
            Object object = null;
            try {
    
                FileInputStream fileIn = mContext.getApplicationContext().openFileInput(filename);
                objectIn = new ObjectInputStream(fileIn);
                object = objectIn.readObject();
    
            } catch (FileNotFoundException e) {
                // Do nothing
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                if (objectIn != null) {
                    try {
                        objectIn.close();
                    } catch (IOException e) {
                        // do nowt
                    }
                }
            }
    
            return object;
        }
    
    
        private static class WriteParams {
    
            Object object;
            String filename;
    
            public WriteParams(Object object, String filename) {
                super();
                this.object = object;
                this.filename = filename;
            }
    
            public Object getObject() {
                return object;
            }
    
            public String getFilename() {
                return filename;
            }
    
        }
    
    }
    

    Then invoke the public methods to kick off the writing/reading. For this version, I also having it taking place in a separate thread, but you could modify that if you needed to.