使用parcelable在Intent中传递数组 [英] Pass array in Intent using parcelable
问题描述
我想在活动之间发送对象数组.我想使用可拆分界面并有意发送数据.但是,我不断收到错误.我被困了2天.这是有关我的问题的一些详细信息.
I would like to send an array of objects between activities. I want to use the parcelable interface and send the data in an intent. However I keep getting errors. I have been stuck for 2 days. Here are some details about my problem.
A级
private ProjetUI[] mProjects;
private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent = new Intent(context, ProjetListActivity.class);
intent.putExtra(ProjetListActivity.ARG_PROJECTS, mProjects);
context.startActivity(intent);
}
};
B类
ProjetUI[] mProjects = getIntent().getParcelableArrayExtra(ARG_PROJECTS);
我收到一个编译错误不兼容的类型"转换为(ProjetUI [])后,出现运行时错误无法将Parcelable []转换为ProjetUI []"
I get a compilation error "Incompatible types" After casting to (ProjetUI[]), I get a runtime error "Cannot cast Parcelable[] to ProjetUI[]"
Class Projet
public class ProjetUI implements Parcelable {
private String id;
private String idParent;
private String nom;
private String description;
private List<ProjetColonneUI> colonnes;
private List<VueUI> vues;
private boolean archive;
private String version;
private String commentaire;
private boolean published;
private List<DroitAccesUI> droitAcces;
private String idDossier;
private String typeDossier;
private String idModele;
private List<ProjetDatasetUI> projetDatasets;
protected ProjetUI(Parcel in) {
id = in.readString();
idParent = in.readString();
nom = in.readString();
description = in.readString();
colonnes = in.createTypedArrayList(ProjetColonneUI.CREATOR);
vues = in.createTypedArrayList(VueUI.CREATOR);
archive = in.readInt() == 1;
version = in.readString();
commentaire = in.readString();
published = in.readInt() == 1;
droitAcces = in.createTypedArrayList(DroitAccesUI.CREATOR);
idDossier = in.readString();
typeDossier = in.readString();
idModele = in.readString();
projetDatasets = in.createTypedArrayList(ProjetDatasetUI.CREATOR);
}
public static final Creator<ProjetUI> CREATOR = new Creator<ProjetUI>() {
@Override
public ProjetUI createFromParcel(Parcel in) {
return new ProjetUI(in);
}
@Override
public ProjetUI[] newArray(int size) {
return new ProjetUI[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(getId());
parcel.writeString(getIdParent());
parcel.writeString(getNom());
parcel.writeString(getDescription());
parcel.writeTypedList(getColonnes());
parcel.writeTypedList(getVues());
parcel.writeInt(isArchive() ? 1 : 0);
parcel.writeString(getVersion());
parcel.writeString(getCommentaire());
parcel.writeInt(isPublished() ? 1 : 0);
parcel.writeTypedList(getDroitAcces());
parcel.writeString(getIdDossier());
parcel.writeString(getTypeDossier());
parcel.writeString(getIdModele());
parcel.writeTypedList(getProjetDatasets());
}
}
编辑
其他类与ProjeUI类一样实现可拆分.这是另一个具有枚举类型的类的示例,以及一个实现parcelable的枚举的示例
The other classes implement parcelable just like ProjeUI class. Here is an example of another class that has an enum type and an example of an enum that implements parcelable
public class VueRelationUI implements Parcelable {
private String id;
private String idVue;
private String idRelation;
private RelationType typeRelation;
protected VueRelationUI(Parcel in) {
id = in.readString();
idVue = in.readString();
idRelation = in.readString();
typeRelation = in.readParcelable(RelationType.class.getClassLoader());
}
public static final Creator<VueRelationUI> CREATOR = new Creator<VueRelationUI>() {
@Override
public VueRelationUI createFromParcel(Parcel in) {
return new VueRelationUI(in);
}
@Override
public VueRelationUI[] newArray(int size) {
return new VueRelationUI[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(getId());
parcel.writeString(getIdVue());
parcel.writeString(getIdRelation());
parcel.writeParcelable(getTypeRelation(), flags);
}
}
ENUM
public enum RelationType implements Parcelable {
INNER,
OUTER;
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(ordinal());
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<RelationType> CREATOR = new Creator<RelationType>() {
@Override
public RelationType createFromParcel(Parcel parcel) {
return RelationType.values()[parcel.readInt()];
}
@Override
public RelationType[] newArray(int size) {
return new RelationType[size];
}
};
}
任何帮助将不胜感激
推荐答案
发生此问题是由于Android的 Parcel
类的内部实现.当您开始新活动时,将打包所有意向附加项,然后将其取消包裹.发生这种情况时,Android框架会分配一个新的 Parcelable []
,并不分配一个新的 ProjetUI []
.因此,当您尝试投射它时,会得到一个 ClassCastException
.
The problem happens because of the internal implementation of Android's Parcel
class. When you start the new activity, all of the intent extras are parceled and then unparceled. When this happens, the Android framework allocates a new Parcelable[]
, and not a new ProjetUI[]
. So you get a ClassCastException
when you try to cast it.
最好的解决方案可能是将代码更改为使用 ArrayList< ProjetUI>
而不是 ProjetUI []
.然后,您可以毫无问题地使用 Intent.putParcelableArrayListExtra()
和 getParcelableArrayListExtra()
.
Probably the best solution would be to change your code to use ArrayList<ProjetUI>
instead of ProjetUI[]
. Then you can use Intent.putParcelableArrayListExtra()
and getParcelableArrayListExtra()
without any problems.
如果由于某种原因不能执行此操作,则必须一次将数组一次强制转换为一个元素:
If you can't do that for some reason, then you will have to manually cast the array one element at a time:
Parcelable[] parcelables = getIntent().getParcelableArrayExtra(ARG_PROJECTS);
ProjetUI[] mProjects = new ProjetUI[parcelables.length];
for (int i = 0; i < parcelables.length; ++i) {
mProjects[i] = (ProjetUI) parcelables[i];
}
这篇关于使用parcelable在Intent中传递数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!