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

我将此对象保存到activites
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);
}
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;jdata.add(新对您必须将以下行作为
onCreate(Bundle)
覆盖中的第一行:

 super.onCreate(savedInstanceState);

这就是您的状态无法正常工作的原因。

应该调用
init()
方法。请在
readFromParcel()
writetparcel()中发布代码
调试显示,它没有被调用…两个构造函数都没有…我添加了读写功能代码你是说
mStackManager
在调用
getParcelable
后实际上不是
null
?听起来很奇怪。我已经看了十几遍这个问题和你的代码,但都看不到任何内容有点不对劲。你的解释没有逻辑意义。我发现了问题…我清理了我的对象(我想,该对象无论如何都会保存到包中,然后会重新创建)…那是错误的,我应该放弃我的引用,没有更多。因为捆绑包只会打包我的对象,如果必要的话,并不总是…它不会在屏幕旋转时打包它例如…实际上,我使用一个活动…你是对的,这将是一个问题,但这也会使我的解决方案失败…我忘记添加
ssuper.onCreate(savedInstanceState)
调用,因为我使用了一些
BaseActivity
,它在
onBeforeCreate
onAfterCreate
中拆分
onCreate
,因此我的基类总是调用
super.onCreate(savedInstanceState)
。。。