gpt4 book ai didi

android - Parcelable 接口(interface)保留对象引用? &Parcelable.CREATOR 是不是叫了?

转载 作者:行者123 更新时间:2023-11-29 20:39:56 26 4
gpt4 key购买 nike

我正在使用 Parcelable 接口(interface)将我的对象传递到 fragment 中。根据 Android 的文档,它是一个“类的接口(interface),其实例可以写入 Parcel 并从中恢复”[1] .
我期待每次当 ParcelableObject 通过 Bundle 传递到另一个 fragment 时,对象被写入 Parcel 然后 Parcelable.CREATOR 应该重新创建对象并初始化对象的变量。
如果我将我的可打包对象 (X) 放入 Bundle 并将该包设置为我的新 fragment 的参数,这对我来说有点意外。然后我在新 fragment 的 onCreateView 方法中从 bundle 中读取我的 parcelable 对象 (Y)。我在 onCreateView (Y) 中获得的对象与我在前一个 fragment 中放入 Bundle 的对象 (X) 相同(意思是 X == Y)。更令人惊讶的是,Parcelable.CREATOR 甚至没有被调用。
他们在 Android 的文档中写到 Bundle:“从 String 值到各种 Parcelable 类型的映射。” [2] .好吧,这也许可以解释为什么写入的对象与读取的对象相同,但为什么他们需要 Parcelable.CREATOR 接口(interface),即使没有它也能正常工作?

现在让我们更具体一点:

我有一个 ParentPagerFragment,它包含一个 ViewPager,它是 3 个 ChildTextViewFragment 的父级

这里是 ParentPagerFragment 实现的重要部分。

@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 只显示一个简单的TextView

ChildTextViewFragment::newInstance 实现

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;
}

ChildTextViewFragment::onCreateView 实现

@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;

}

我的实体:

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,这里是演示控制流的日志。

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

请注意对象标识在创建和读取时是相同的。

这是在 fragment 之间传递对象的正确方法吗?在哪些情况下调用 Parcelable.CREATOR 接口(interface)?

谢谢你的帮助!

最佳答案

So ok that's maybe what explains why is the written object identical with the read one, but why they need the Parcelable.CREATOR interface when it works as correct even without it ?

您的 Parcelable 未放入 Parcel 中,因此未使用 Parcelable.CREATOR

Parcel 涉及IPC。因此,如果您尝试通过 startActivity() 额外传递相同的 Intent,那将涉及您的 CREATOR,如 startActivity()涉及IPC。

配置更改可能涉及包裹(他们可能会优化这种情况)。如果您的进程在后台终止,并且用户通过最近任务列表快速返回到您正在运行的任务,这将涉及一个 Parcel 和一个 CREATOR

关于android - Parcelable 接口(interface)保留对象引用? &Parcelable.CREATOR 是不是叫了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31115368/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com