Передать массив в Intent, используя посылки

Я хотел бы отправить массив объектов между действиями. Я хочу использовать пакетный интерфейс и отправлять данные в намерении. Однако я продолжаю получать ошибки. Я застрял на 2 дня. Вот некоторые подробности о моей проблеме.

Класс А

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

Класс Б

ProjetUI[] mProjects = getIntent().getParcelableArrayExtra(ARG_PROJECTS);

Я получаю сообщение об ошибке компиляции «Несовместимые типы». После приведения к (ProjetUI[]) я получаю ошибку времени выполнения «Невозможно преобразовать Parcelable[] в ProjetUI[]»

Классный проект

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. Вот пример другого класса, который имеет тип перечисления, и пример перечисления, реализующего разделяемость.

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

Мы будем очень признательны за любую помощь


person Youssef Ghrib    schedule 06.08.2018    source источник
comment
Пожалуйста, поделитесь полной трассировкой стека? и правильно ли другие классы реализуют посылки?   -  person H. Ekici    schedule 06.08.2018
comment
Рекомендую Парселер. Это делает этот материал намного проще. github.com/johncarl81/parceler   -  person nasch    schedule 07.08.2018
comment
Я это проверю. Тем не менее, я бы предпочел понять, что я делаю неправильно здесь.   -  person Youssef Ghrib    schedule 07.08.2018
comment
добавьте также код проектной активности   -  person nishant    schedule 07.08.2018


Ответы (1)


Проблема возникает из-за внутренней реализации класса Android Parcel. Когда вы начинаете новую деятельность, все дополнительные намерения разделяются, а затем распаковываются. Когда это происходит, платформа 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];
}
person Ben P.    schedule 06.08.2018
comment
Большое спасибо, ручной подход сработал. Я посмотрю, как изменить свой код на ArrayList - person Youssef Ghrib; 07.08.2018