使用parcelable在Intent中传递数组
Pass array in Intent using parcelable
我想在活动之间发送一组对象。我想使用 parcelable 接口并以意图发送数据。但是我不断收到错误。我被困了2天。以下是有关我的问题的一些详细信息。
Class一个
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);
}
};
Class B
ProjetUI[] mProjects = getIntent().getParcelableArrayExtra(ARG_PROJECTS);
我遇到编译错误"Incompatible types"
投射到 (ProjetUI[]) 后,出现运行时错误 "Cannot cast Parcelable[] to ProjetUI[]"
Class 项目
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());
}
}
编辑
This is the complete stacktrace
其他 classes 像 ProjeUI class 一样实现 parcelable。
这是另一个 class 具有枚举类型的示例和一个实现 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);
}
}
枚举
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
class 的内部实现。当您启动新的 activity 时,所有的 intent extra 都被打包然后解包。发生这种情况时,Android 框架会分配一个新的 Parcelable[]
,而 不会 分配一个新的 ProjetUI[]
。所以当你尝试施放它时你会得到一个ClassCastException
。
最好的解决方案可能是更改您的代码以使用 ArrayList<ProjetUI>
而不是 ProjetUI[]
。然后你可以毫无问题地使用Intent.putParcelableArrayListExtra()
和getParcelableArrayListExtra()
。
如果由于某种原因您不能这样做,那么您将不得不一次一个地手动转换数组:
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 接口并以意图发送数据。但是我不断收到错误。我被困了2天。以下是有关我的问题的一些详细信息。
Class一个
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);
}
};
Class B
ProjetUI[] mProjects = getIntent().getParcelableArrayExtra(ARG_PROJECTS);
我遇到编译错误"Incompatible types" 投射到 (ProjetUI[]) 后,出现运行时错误 "Cannot cast Parcelable[] to ProjetUI[]"
Class 项目
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());
}
}
编辑
This is the complete stacktrace
其他 classes 像 ProjeUI class 一样实现 parcelable。 这是另一个 class 具有枚举类型的示例和一个实现 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);
}
}
枚举
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
class 的内部实现。当您启动新的 activity 时,所有的 intent extra 都被打包然后解包。发生这种情况时,Android 框架会分配一个新的 Parcelable[]
,而 不会 分配一个新的 ProjetUI[]
。所以当你尝试施放它时你会得到一个ClassCastException
。
最好的解决方案可能是更改您的代码以使用 ArrayList<ProjetUI>
而不是 ProjetUI[]
。然后你可以毫无问题地使用Intent.putParcelableArrayListExtra()
和getParcelableArrayListExtra()
。
如果由于某种原因您不能这样做,那么您将不得不一次一个地手动转换数组:
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];
}