Android 从捆绑包创建包裹不会调用构造函数
我有一个类实现了Android 从捆绑包创建包裹不会调用构造函数,android,android-activity,bundle,parcel,Android,Android Activity,Bundle,Parcel,我有一个类实现了Parcelable 我将此对象保存到activitesonSaveInstanceState中的捆绑包中,并尝试在onCreate中重新创建该对象。如下所示: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { // this
Parcelable
我将此对象保存到activitesonSaveInstanceState
中的捆绑包中,并尝试在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);
}
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);
}
}
}
创建Parcelable类时,它应该调用Parcelable类的协构造函数,不是吗?我的parcelable类是从bundle中检索到的,但它看起来不像保存的对象,甚至没有初始化
我的简化parcelable类如下所示:
@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);
}
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);
}
}
}
public类BackstackManager实现可包裹
{
公共静态最终字符串标记=BackstackManager.class.getName();
私有列表,对>>>();
msavestatemap=新HashMap();
}
// ----------------------
//包裹的
// ----------------------
公共静态最终包裹。创建者=
新建Parcelable.Creator()
{
@凌驾
公共BackbackManager createFromParcel(地块源)
{
返回新的BackbackManager(源);
}
@凌驾
公共BackstackManager[]新数组(整数大小)
{
返回新BackbackManager[大小];
}
};
公共BackstackManager(包裹源)
{
init();
readFromParcel(来源);
}
@凌驾
公共int描述内容()
{
返回0;
}
@凌驾
公共无效写入包裹(包裹目的地,内部标志)
{
dest.writeInt(mBackstack.size());
对于(int i=0;i>();
int dataSize=source.readInt();
对于(int j=0;j data.add(新对您必须将以下行作为onCreate(Bundle)
覆盖中的第一行:
super.onCreate(savedInstanceState);
这就是您的状态无法正常工作的原因。应该调用init()
方法。请在readFromParcel()
和writetparcel()中发布代码
调试显示,它没有被调用…两个构造函数都没有…我添加了读写功能代码你是说mStackManager
在调用getParcelable
后实际上不是null
?听起来很奇怪。我已经看了十几遍这个问题和你的代码,但都看不到任何内容有点不对劲。你的解释没有逻辑意义。我发现了问题…我清理了我的对象(我想,该对象无论如何都会保存到包中,然后会重新创建)…那是错误的,我应该放弃我的引用,没有更多。因为捆绑包只会打包我的对象,如果必要的话,并不总是…它不会在屏幕旋转时打包它例如…实际上,我使用一个活动…你是对的,这将是一个问题,但这也会使我的解决方案失败…我忘记添加ssuper.onCreate(savedInstanceState)
调用,因为我使用了一些BaseActivity
,它在onBeforeCreate
和onAfterCreate
中拆分onCreate
,因此我的基类总是调用super.onCreate(savedInstanceState)
。。。