【发布时间】:2014-11-04 13:20:30
【问题描述】:
我有一个实现Parcelable 的类。
我在活动onSaveInstanceState 中将该对象安全地保存到捆绑包中,并尝试在onCreate 中重新创建该对象。如下所示:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
{
// this line does NOT call my constructor, why not?
// AND I don't get the same object as before => I get an uninitialised object
mStackManager = savedInstanceState.getParcelable(BackstackManager.TAG);
// the list and map in the object are NULL after this...
}
else
{
mStackManager = new BackstackManager();
...
}
}
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putParcelable(BackstackManager.TAG, mStackManager);
}
创建 Parcelable 类时,它应该调用 Parcelable 类的构造函数,不是吗?我的 parcelable 类是从包中检索到的,但它看起来不像保存的对象,甚至没有初始化...
我的简化 Parcelable 类如下所示:
public class BackstackManager implements Parcelable
{
public static final String TAG = BackstackManager.class.getName();
private List<List<Pair<Class<?>, Pair<Integer, String>>>> mBackstack;
private Map<String, Fragment.SavedState> mSavedStateMap;
public BackstackManager()
{
init();
}
private void init()
{
mBackstack = new ArrayList<List<Pair<Class<?>, Pair<Integer, String>>>>();
mSavedStateMap = new HashMap<String, Fragment.SavedState>();
}
// ----------------------
// Parcelable
// ----------------------
public static final Parcelable.Creator<BackstackManager> CREATOR =
new Parcelable.Creator<BackstackManager>()
{
@Override
public BackstackManager createFromParcel(Parcel source)
{
return new BackstackManager(source);
}
@Override
public BackstackManager[] newArray(int size)
{
return new BackstackManager[size];
}
};
public BackstackManager(Parcel source)
{
init();
readFromParcel(source);
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mBackstack.size());
for (int i = 0; i < mBackstack.size(); i++)
{
List<Pair<Class<?>, Pair<Integer, String>>> data = mBackstack.get(i);
dest.writeInt(data.size());
for (int j = 0; j < data.size(); j++)
{
Class<?> clazz = data.get(j).first;
Integer id = data.get(j).second.first;
String tag = data.get(j).second.second;
Fragment f = mFragmentManager.findFragmentByTag(tag);
// 1) save backstack data
ParcelBundleUtils.writeStringNullSafe(dest, clazz != null ? clazz.getName() : null);
dest.writeInt(id);
dest.writeString(tag);
// 2) save fragment state, if possible
ParcelBundleUtils.writeBoolean(dest, f != null);
if (f != null)
ParcelBundleUtils.writeParcelableNullSafe(dest, mFragmentManager.saveFragmentInstanceState(f), 0);
}
}
}
public void readFromParcel(Parcel source)
{
int backstackSize = source.readInt();
for (int i = 0; i < backstackSize; i++)
{
ArrayList<Pair<Class<?>, Pair<Integer, String>>> data = new ArrayList<Pair<Class<?>, Pair<Integer, String>>>();
int dataSize = source.readInt();
for (int j = 0; j < dataSize; j++)
{
// 1) read backstack data
String clazzName = ParcelBundleUtils.readStringNullSafe(source);
Class<?> clazz = null;
if (clazzName != null)
{
try
{
clazz = Class.forName(clazzName);
}
catch (ClassNotFoundException e)
{
L.e(this, e);
}
}
Integer id = source.readInt();
String tag = source.readString();
// 2) read fragment state if possible
boolean savedStateExists = ParcelBundleUtils.readBoolean(source);
if (savedStateExists)
{
SavedState state = ParcelBundleUtils.readParcelableNullSafe(source, SavedState.class.getClassLoader());
if (state != null)
mSavedStateMap.put(tag, state);
}
data.add(new Pair<Class<?>, Pair<Integer, String>>(clazz, new Pair<Integer, String>(id, tag)));
}
mBackstack.add(data);
}
}
}
我的ParcelBundleUtils 只是写一点,如果一个对象是否为空,并且依赖于读/写实际对象...
编辑
我当前的解决方法是使用与包裹读/写功能相同的包的读/写功能(我复制并粘贴了我的代码,只是替换了读/写功能),但写入数据直接打包...但我真的很想知道,为什么上面不能作为包裹使用
编辑 2
我发现以下内容:Android: Parcelable.writeToParcel and Parcelable.Creator.createFromParcel are never called
但如果这就是问题所在,我不会是唯一一个面临这个问题的人......
【问题讨论】:
-
应该调用你的
init()方法。请将代码发布在readFromParcel()和writeToParcel() -
调试显示,它没有被调用……构造函数都没有……我添加了读写功能代码
-
你是说
mStackManager在你调用getParcelable之后实际上不是null? -
听起来很奇怪。我已经看过这个问题和你的代码十几次了,看不出有什么问题。你的解释没有逻辑意义。
-
我发现了问题...我的活动
onDestroy我清理了我的对象(我想,对象无论如何都会保存到捆绑包中,然后会重新创建)...这是错误的,我应该放弃我的参考资料,仅此而已。因为捆绑只会包裹我的对象,如果有必要,不总是……它不会在屏幕旋转时包裹它……
标签: android android-activity bundle parcel