如何在Activity重新启动时保留一个复杂的对象?

假设我有一个可序列化的Java Bean对象。 我想要在活动通过onDestroy() 时有目的的安全地存储它(即调用onSaveInstanceState())。

我正在寻找一种不涉及创build数据库和写入对象的方式(主要是因为a)Android的数据库API是可怕的,b)由于数据库使应用程序更新成为一场噩梦,因为没有体面的支持应用迁移)。

我想过将对象序列化为ByteArrayOutputStream,base64将其编码并将其作为string写入SharedPreferences文件。 或者那太遥远了?

UPDATE

也许序列化到string的想法毕竟不是那么糟糕,似乎工作得很好。 这是我现在正在做的事情:

public static String objectToString(Serializable object) { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { new ObjectOutputStream(out).writeObject(object); byte[] data = out.toByteArray(); out.close(); out = new ByteArrayOutputStream(); Base64OutputStream b64 = new Base64OutputStream(out); b64.write(data); b64.close(); out.close(); return new String(out.toByteArray()); } catch (IOException e) { e.printStackTrace(); } return null; } public static Object stringToObject(String encodedObject) { try { return new ObjectInputStream(new Base64InputStream( new ByteArrayInputStream(encodedObject.getBytes()))).readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } 

在onDestroy()然后,我可以简单地将Base64string写入一个首选项文件,在这个文件中它是安全的,直到我在下次活动启动时再次读取它。 这比我预期的要快得多,除非你的豆子传输了大量的数据,它工作得很好。 甚至更好的是,您不必维护数据库模式。

不过,我很好奇别人如何做到这一点。

Solutions Collecting From Web of "如何在Activity重新启动时保留一个复杂的对象?"

我正在寻找一种不涉及创build数据库和写入对象的方式(主要是因为a)Android的数据库API是可怕的,b)由于数据库使应用程序更新成为一场噩梦,因为没有体面的支持应用迁移)。

Android的API实际上是相当合理的,主要是因为它是SQLite API的一个精简包装器,SQLite API对于embedded式数据库来说是相当合理的。 而且,Android通过SQLiteOpenHelper为应用程序升级的模式升级提供了帮助。

这比我预期的要快得多,除非你的豆子传输了大量的数据,它工作得很好。

我听说有更多的开发人员从序列化中尖叫起来,而我听说有长期成功的人。 就在这几天,在SO#这里,我和一个人拼命地试图从根本上撕掉他的应用程序的序列化。

甚至更好的是,您不必维护数据库模式。

哦,是的,你呢。 当你更新你的应用程序和你的class级被修改时,你认为会发生什么? 做logging来弄清楚如何从一个新版本的类反序列化旧版本的类是一件苦差事,是开发人员放弃序列化的原因之一。 另外,不要忘记序列化不是事务性的,而SQLite是。

我也在寻找un / marshalling任何bean或活动状态的好方法。 我们都知道Activity的onStoreInstanceState()和onRestoreInstanceState()是多么的痛苦。

我的活动只是将它们的状态存储在onPause()中,并通过直接对象序列化将它们恢复到onCreate()生命周期钩子中。

像你一样,通过string进行序列化当然可能,但不太适合大数据,并导致大量的开销。 此外,首选项实际上是存储首选项,而不是数据:)不幸的是,Parcelable / Parcel我们可以用于此目的,不build议存储到持久性存储。

所以剩下的就是一个简单的对象序列化 – 幸运的是,android SDK已经实现了ObjectInputStream和ObjectOutputStream类,带来了所有的缺点和好处 – 就像我们也会在非Java的Java世界中做的那样简单:

 ObjectOutputStream.writeObject(yourPojo) 

会做我们的魔术,(记得实现Serializable标记接口)

此外,您可能需要查看Context-ContextWrapper-Activity的以下API,这对caching本地数据(如图像)非常有用:

 .getCacheDir() .getDir() .openFileInput() .openFileOutput() 

快乐黑客:)