Android:Parcelable.writeToParcel 和 Parcelable.Creator.createFromParcel 永远不会被调用
我对在这里发布问题完全陌生,但是多年来我一直在这里阅读很多内容。通常情况下,我总是能够通过彻底搜索网络来找到答案,但这次我不知所措......
在又花了一天的时间试图找出为什么这不起作用之后,我决定寻求帮助,希望你们可以给我一些建议,或者更好的解决方案。
问题: 在 Android 游戏中,我必须让应用程序记住其状态(例如,当用户按下主屏幕按钮时)。经过一番搜索后,我意识到,为了使我的类在重新打开应用程序后初始化回适当的状态,我必须支持 Parcelable 接口以将它们与 Bundle 一起传递。
在我的 onStop 和 onStart 函数中,我分别将游戏状态保存到 Bundle 和从 Bundle 恢复游戏状态,但是当我在 Bundle 上调用 putParcelable 和 getParcelable 函数时,永远不会调用对象的 writeToParcel 和 createFromParcel 函数。
由于担心这可能是由于游戏的相对复杂性造成的,我认为最好创建一个非常简单的应用程序来尝试让它工作。
基于我在网上看到的许多 Parcelable 示例,这成为了我的课程:
public class ParcelableTest implements Parcelable {
int id;
public ParcelableTest(int newID)
{
id = newID;
}
private ParcelableTest(Parcel in) {
readFromParcel(in);
}
public void writeToParcel(Parcel out, int arg1) {
writeToParcel(out);
}
public void writeToParcel(Parcel out) {
Log.v("ParcelableTest","Writing to parcel");
out.writeInt(id);
}
public void readFromParcel(Parcel in) {
id = in.readInt();
}
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<ParcelableTest> CREATOR = new
Parcelable.Creator<ParcelableTest>() {
public ParcelableTest createFromParcel(Parcel in) {
Log.v("ParcelableTest","Creating from parcel");
return new ParcelableTest(in);
}
public ParcelableTest[] newArray(int size) {
return new ParcelableTest[size];
}
};
}
并且从我的 Main 活动中,我将调用以下函数来保存/恢复数据:
public Bundle saveToBundle(Bundle savedState)
{
savedState.putParcelable("Test1",mTest1);
savedState.putParcelable("Test2",mTest2);
return savedState;
}
public void restoreFromBundle(Bundle savedState)
{
mTest1 = savedState.getParcelable("Test1");
mTest2 = savedState.getParcelable("Test2");
}
但由于某种原因,这两个函数(使用 putParcelable 和 getParcelable 函数)都不会在我的测试类中产生适当的 Parcelable 调用。
最奇怪的是,它确实以某种方式读取了正确的值(我尝试过在类中使用更多变量),但我的调试和日志显示应用程序永远无法写入 writeToParcel 和 createFromParcel。
我在这里缺少什么?
任何帮助/想法将不胜感激。
I'm totally new to posting questions on here, however I have been reading a lot on here for years. Normally I always am able to find my answers by thoroughly searching the web, but this time I am at a loss...
After having spent yet another day of trying to figure out why this is not working I decided to ask for help, hoping you guys can give me a few pointers, or better, a solution.
The problem:
In an Android game I have come to the point where I have to make the application remember its state when a user e.g. presses the HOME-screen button. After some searches I realised that in order to make my classes initialize back to their appropriate states after re-opening the application I had to support the Parcelable interface to pass them with the Bundle.
In my onStop and onStart functions I respectively save and restore the game state to and from a Bundle, however when I call the putParcelable and getParcelable functions on the Bundle the object's writeToParcel and createFromParcel functions are never called.
Fearing that this may have been due to the relative complexity of the game I figured I had best create a very simple application to try to get it to work.
Based on many Parcelable examples I have seen online, this became my class:
public class ParcelableTest implements Parcelable {
int id;
public ParcelableTest(int newID)
{
id = newID;
}
private ParcelableTest(Parcel in) {
readFromParcel(in);
}
public void writeToParcel(Parcel out, int arg1) {
writeToParcel(out);
}
public void writeToParcel(Parcel out) {
Log.v("ParcelableTest","Writing to parcel");
out.writeInt(id);
}
public void readFromParcel(Parcel in) {
id = in.readInt();
}
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<ParcelableTest> CREATOR = new
Parcelable.Creator<ParcelableTest>() {
public ParcelableTest createFromParcel(Parcel in) {
Log.v("ParcelableTest","Creating from parcel");
return new ParcelableTest(in);
}
public ParcelableTest[] newArray(int size) {
return new ParcelableTest[size];
}
};
}
And from my Main activity I would call the following functions to save / restore the data:
public Bundle saveToBundle(Bundle savedState)
{
savedState.putParcelable("Test1",mTest1);
savedState.putParcelable("Test2",mTest2);
return savedState;
}
public void restoreFromBundle(Bundle savedState)
{
mTest1 = savedState.getParcelable("Test1");
mTest2 = savedState.getParcelable("Test2");
}
But for some reason neither of the functions (with the putParcelable and getParcelable functions) will result in the appropriate Parcelable calls in my test class.
The strangest thing is that it does somehow read the correct values (I have tried with more variables in the class), but my debugging and my log shows that tha application never gets to writeToParcel and createFromParcel.
What am I missing here?
Any help / thoughts would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
显然,Android Bundle 类不遵守可打包协议,而是在 IPC 编组过程中遵循的协议。
相反,Bundle 实现似乎只是通过反射的方式将 Parcelable 对象写入和读取到其自己的内部映射中。从我们所做的测试来看,Bundle 似乎会写入/读取 Parcelable 派生类中定义的每个字段,只是因为您已经声明了这些字段。
Apparently the Android Bundle class does not adhere to the parcelable protocol that instead is followed during IPC marshalling.
Instead, it seems like the Bundle implementation just writes and reads the Parcelable object into its own internal map by means of reflection. From a test we did, it seems that the Bundle writes/reads every field defined in your Parcelable-derived class, just because you have declared those fields.
从技术上讲,文档并没有说从
onSaveInstance
调用writeToParcel
或createFromParcel
。事实上,如果您检查代码中的savedState
,您会发现它在保存和恢复情况下都是完全相同的对象实例;如果可以的话,避免序列化-反序列化是有意义的。OTOH,文档也没有说序列化尚未完成。结论应该是您不应该依赖于任何一种情况,只需假设您获得了正确的捆绑包即可。
另外,您可能需要检查 http://developer.android.com/指南/主题/资源/runtime-changes.html
Technically, the documentation doesn't say that
writeToParcel
orcreateFromParcel
are called fromonSaveInstance
. As a matter of fact, if you check thesavedState
in your code you are going to find that it is exactly the same object instance in both the save and the restore cases; it makes sense to avoid serialize-deserialize if you can.OTOH, the documentation doesn't say either that serialization is not done. The conclusion should be that you shouldn't depend on either case, just assume that you get the correct bundle.
Also, you may want to check http://developer.android.com/guide/topics/resources/runtime-changes.html
我证实了superjos所说的。
在 saveToBundle 事件中,Android 包仅存储每次反射的类成员,并且不调用 Parcelable 函数。
我在这个问题上损失了一天!悲伤......
这真的很糟糕......这意味着您可能使用这种方式存储大量数据。
I confirm what superjos said.
On the saveToBundle event, Android bundle just stores the class's members per reflection and doesn't call the Parcelable functions.
I have lost one day on this problem! sad....
This is really bad .... This means you potentially stores a huge amount of data for nothing using this way.