【发布时间】:2011-08-24 13:52:52
【问题描述】:
我正在开发一个必须跨活动维护全局状态的 android 项目。为此,我正在成功扩展应用程序。然而,该项目的一个新要求是即使应用程序被 android OS 杀死也要保持状态,对于这个简单的扩展应用程序是不够的,因为对象将与应用程序一起被杀死。
为了解决这个问题,我对扩展 Application 的对象实现了 Serializable:
public class AppState extends Application implements Serializable
然后当主要活动被销毁时,我将对象写入私有存储:
@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();
}
}
}
}
}
然后我通过调用来恢复对象:
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();
}
}
}
}
效果很好,但我很好奇有多少人使用过这种方法。我认为这会很常见,因为我读过很多关于人们想要更永久地保存状态的信息。但令我惊讶的是,谷歌搜索“'extends Application implements Serializable' android”返回了 0 个结果。由于某种原因,这不是推荐的方法吗?否则,它可以作为其他面临相同问题的人的解决方案。
【问题讨论】:
-
大声笑不要在应用程序上实现可序列化。而是创建一个 Singleton 对象,其中包含您想要的所有变量。然后,您可以使其可序列化并使用它。
-
我很想知道它是否能正常工作,因为我已经在使用应用程序,所以很容易测试它。但后果会是什么?
-
它确实有效。这就是为什么我问这是否出于某种原因是不好的做法。
-
您没有显示您存储的变量,但我假设您将瞬态置于上下文等中,因此这意味着您还可以有一个单独的类来存储您的状态。这是不好的做法,因为它是代码膨胀/不必要的耦合/如果需要重构则无济于事/如果涉及到它则无法调试/丑陋!
-
我在 AppState 类中只有私有成员和他们的 getter/setter。没有像
onCreate()或上下文这样的其他实现。不过,我不得不在一些不可序列化的对象上添加瞬态。
标签: android serialization