问题
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
回答1:
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.
回答2:
Using static in your example leads to memory leaks and is not a good way to do anything.
I suggest using static only in 3 cases:
- static final String or int - constants
- on inner classes (so that they don't contain reference to outer class)
- on util or in some cases (like CustomFragment.newInstance) factory methods
The question is why would you want to persist PendingIntent? Its usecase is for inter-process-communication.
回答3:
Binder
Most developers will not implement this class directly, instead using the aidl tool to describe the desired interface, having it generate the appropriate Binder subclass.
from the official documentation
Do you need to store the Binder
object with the rest of your object? Maybe you can save your object without the Binder
instance, and re-create the Binder
object with aidl
after you restore the object
来源:https://stackoverflow.com/questions/15841997/saving-parcelable-data