I'm working on an android project that have to maintain global state across activities. For this I'm extending Application successfully. However a new requirement for the project is to maintain state even if the application is killed by android OS, and for this simply extending Application will not be enough since the object will be killed along with the app.
To solve this I have implemented Serializable to the object that extends Application:
public class AppState extends Application implements Serializable
and then I write the object to private storage when the main activity is destroyed:
@Override
public void onDestroy() {
super.onDestroy();
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
FileOutputStream fos = null;
// If there's a certificate creation in progress, let's store it more
// permanently before killing the app.
if (appState.getCertificate() != null) {
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(appState);
byte[] buf = bos.toByteArray();
fos = openFileOutput(Constants.objectStoreFileName, Context.MODE_PRIVATE);
fos.write(buf);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Then I restore the object by calling:
private void getAppStateFromFile() {
FileInputStream fis = null;
ObjectInputStream ois = null;
ByteArrayOutputStream bos = null;
try {
fis = openFileInput(Constants.objectStoreFileName);
bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fis.read(b)) != -1) {
bos.write(b, 0, bytesRead);
}
byte[] bytes = bos.toByteArray();
ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
AppState appStateFromFile = (AppState) ois.readObject();
if (appStateFromFile != null) {
// restore values from appStateFromFile
}
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (OptionalDataException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
deleteFile(Constants.objectStoreFileName);
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
It's working fine, but I got curious to how many have used this approach. I thought it would be quite common since I have read a lot about people wanting to save state more permanently. But to my开发者_JS百科 surprice googling on "'extends Application implements Serializable' android" returned 0 results. Is this not a recommended approach for some reason? Otherwise it could serve as a solution to others facing the same problem.
SharedPreferences
enables you to save state in the way that you want, so the global variables are updated in SharedPreferences
when changes are made in the Application
object.
Using Application for global state is good, though I'm not sure relying on onDestroy
to be called in the Application is the best to go.
When onCreate
is called again in the Application
you can re-initiate the state.
精彩评论