Android 可包裹接口是否保留对象引用&;不调用Parcelable.CREATOR吗?
我正在使用Parcelable接口将对象传递到片段中。根据Android的文档,它是一个“类的接口,这些类的实例可以写入包中并从包中恢复”。Android 可包裹接口是否保留对象引用&;不调用Parcelable.CREATOR吗?,android,android-fragments,parcelable,parcel,Android,Android Fragments,Parcelable,Parcel,我正在使用Parcelable接口将对象传递到片段中。根据Android的文档,它是一个“类的接口,这些类的实例可以写入包中并从包中恢复”。 我希望每次通过包将ParcelableObject传递到另一个片段时,该对象都会写入Parcelable,然后Parcelable.CREATOR应该重新创建该对象并初始化该对象的变量。 如果我将我的可包裹对象(X)放入包中,并将此包设置为新片段的参数,我会感到有点惊讶。然后,我在新片段的onCreateView方法中从bundle读取我的可包裹对象(Y)
我希望每次通过包将ParcelableObject传递到另一个片段时,该对象都会写入Parcelable,然后Parcelable.CREATOR应该重新创建该对象并初始化该对象的变量。
如果我将我的可包裹对象(X)放入包中,并将此包设置为新片段的参数,我会感到有点惊讶。然后,我在新片段的onCreateView方法中从bundle读取我的可包裹对象(Y)。我在onCreateView中得到的对象(Y)与我在前一个片段中放入Bundle的对象(X)相同(意思是X==Y)。更令人惊讶的是,Parcelable.CREATOR甚至没有被调用。
他们在Android的Docubundle中写道:“从字符串值到各种可打包类型的映射。”。好吧,这也许可以解释为什么写的对象和读的对象是一样的,但是为什么他们需要Parcelable.CREATOR接口,即使没有它也能正常工作 现在让我们更具体一些: 我有一个
ParentPagerFragment
,其中包含一个ViewPager,它是3ChildTextViewFragment
下面是ParentPagerFragment
impl的重要部分
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager, container, false);
List<ChildTextViewFragment> viewFragments = new ArrayList<>();
MyEntity mEntity1 = new MyEntity();
mEntity1.setId(1l);
MyEntity mEntity2 = new MyEntity();
mEntity2.setId(2l);
MyEntity mEntity3 = new MyEntity();
mEntity3.setId(3l);
viewFragments.add(ChildTextViewFragment.newInstance(mEntity1));
viewFragments.add(ChildTextViewFragment.newInstance(mEntity2));
viewFragments.add(ChildTextViewFragment.newInstance(mEntity3));
MyPagerAdapter mPagerAdapter = new MyPagerAdapter(getChildFragmentManager(), viewFragments);
ViewPager mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setAdapter(mPagerAdapter);
return v;
}
ChildTextViewFragment::onCreateView实现
public static ChildTextViewFragment newInstance(MyEntity mEntity) {
ChildTextViewFragment fragment = new ChildTextViewFragment();
Bundle bundle = new Bundle();
Log.d(MyEntityParcelable.TAG, "ChildTextViewFragment::newInstance : creating Parcelable : mEntity has ID = "+ mEntity.getId() +" mEntity = " + mEntity);
MyEntityParcelable entityPar = new MyEntityParcelable(mEntity);
bundle.putParcelable(M_ENTITY_KEY, entityPar);
fragment.setArguments(bundle);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_text, container, false);
TextView mTextView = (TextView) view.findViewById(R.id.textView1);
MyEntityParcelable mEntityPar = getArguments().getParcelable(M_ENTITY_KEY);
MyEntity mEntity = mEntityPar.getMyEntity();
Log.d(MyEntityParcelable.TAG, "ChildTextViewFragment::onCreateView : reading Parcelable : mEntity has ID = "+mEntity.getId()+" mEntity = " + mEntity);
mTextView.setText("my id is: " + Long.toString(mEntity.getId()));
return view;
}
MyEntity:
public class MyEntity {
private long id;
private String name;
private String description;
private String owner;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
}
MyEntityParcelable
public class MyEntityParcelable implements Parcelable {
public static final String TAG = "PARCELABLE_TESTING";
private MyEntity myEntity;
public MyEntityParcelable(MyEntity mEntity) {
this.myEntity = mEntity;
}
private MyEntityParcelable(Parcel in) {
Log.d(TAG, "MyEntityParcelable::Parcel constructor : creating MyEntity from Parcel");
myEntity = new MyEntity();
myEntity.setId(in.readLong());
myEntity.setName(in.readString());
myEntity.setDescription(in.readString());
myEntity.setOwner(in.readString());
}
@Override
public int describeContents() {
return this.hashCode();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
Log.d(TAG, "MyEntityParcelable::writeToParcel : writing myEntity with ID = " + myEntity.getId() + " to Parcel");
dest.writeLong(myEntity.getId());
dest.writeString(myEntity.getName());
dest.writeString(myEntity.getDescription());
dest.writeString(myEntity.getOwner());
}
/*
* Parcelable interface must also have a static field called CREATOR, which
* is an object implementing the Parcelable.Creator interface. Used to
* un-marshal or de-serialize object from Parcel.
*/
public static final Parcelable.Creator<MyEntityParcelable> CREATOR = new Parcelable.Creator<MyEntityParcelable>() {
public MyEntityParcelable createFromParcel(Parcel in) {
return new MyEntityParcelable(in);
}
public MyEntityParcelable[] newArray(int size) {
return new MyEntityParcelable[size];
}
};
public MyEntity getMyEntity() {
return myEntity;
}
}
请注意,对象标识在创建和读取时是相同的
这是在片段之间传递对象的正确方法吗?
在哪些情况下调用Parcelable.CREATOR接口
谢谢你的帮助
好吧,这也许可以解释为什么写的对象和读的对象是一样的,但是为什么他们需要Parcelable.CREATOR接口,即使没有它也能正常工作
您的包裹
未放入包裹
,因此未使用包裹创建者
IPC涉及一个包裹
。因此,如果您尝试通过startActivity()
传递相同的Intent
额外信息,这将涉及到您的创建者,就像startActivity()
涉及IPC一样
配置更改可能涉及一个包
(它们可能会优化此场景)。如果您的进程在后台被终止,并且用户通过最近的任务列表快速返回到您正在运行的任务,那么这将涉及一个包裹
和一个创建者
13:55:14.946: ChildTextViewFragment::newInstance : creating Parcelable : mEntity has ID = 1 mEntity = com.example.nestedfragments.MyEntity@21208247
13:55:14.951: ChildTextViewFragment::newInstance : creating Parcelable : mEntity has ID = 2 mEntity = com.example.nestedfragments.MyEntity@1ecfc4f8
13:55:14.952: ChildTextViewFragment::newInstance : creating Parcelable : mEntity has ID = 3 mEntity = com.example.nestedfragments.MyEntity@3c4a9dd1
13:55:15.069: ChildTextViewFragment::onCreateView : reading Parcelable : mEntity has ID = 1 mEntity = com.example.nestedfragments.MyEntity@21208247
13:55:15.071: ChildTextViewFragment::onCreateView : reading Parcelable : mEntity has ID = 2 mEntity = com.example.nestedfragments.MyEntity@1ecfc4f8
13:55:33.614: ChildTextViewFragment::onCreateView : reading Parcelable : mEntity has ID = 3 mEntity = com.example.nestedfragments.MyEntity@3c4a9dd1