web-dev-qa-db-fra.com

Le protocole Parcelable nécessite un objet Parcelable.Creator appelé CREATOR (j'ai CREATOR)

J'essaie de transmettre des données parcellaires d'une intention à une autre et voici l'erreur que j'obtiens:

08-31 14:12:22.709: E/AndroidRuntime(9931): FATAL EXCEPTION: main
08-31 14:12:22.709: E/AndroidRuntime(9931): Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.matejsoftware.cardscoretracker/com.matejsoftware.cardscoretracker.Igra}: Android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called  CREATOR on class com.matejsoftware.cardscoretracker.Novaigra$Player

La chose est: j'ai un objet Parcelable.Creator. Je posterai l'intégralité du code Parcelable ci-dessous:

public class Player implements Parcelable{
    String name;
    int score;
    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(score);
    }

    public Player(Parcel source){
        score = source.readInt();
        name = source.readString();
    }

    public Player(int score, String name){
        this.score = score;
        this.name = name;
    }
}

public class MyCreator implements Parcelable.Creator<Player> {

    @Override
    public Player createFromParcel(Parcel source) {
        return new Player(source);
    }

    @Override
    public Player[] newArray(int size) {
        return new Player[size];
    }

}

Y a-t-il quelque chose de mal avec le CRÉATEUR? L'application se bloque dès que je clique sur le bouton pour démarrer la prochaine activité.

Voici comment je "récupère" les données parcellaires dans la deuxième activité:

//global variable
ArrayList<Player> playersParceledData;

//This is in onCreate
playersData = getIntent();
playersParceledData = playersData.getParcelableArrayListExtra("parceledData");

Aussi, voici comment je mets des objets de classe à ParcelableArrayListExtra:

Player newPlayer = new Player(0, text);
playersParceledData.add(newPlayer);
zacniIgro.putParcelableArrayListExtra("parceledData", playersParceledData);
24
Guy

Vous avez une séquence différente lors de la lecture de Parcel que celle que vous écrivez.

Dans writeToParcel() vous mettez d'abord String mais dans HeatFriendDetail(Parcel in), vous lisez d'abord entier. Ce n'est pas la bonne façon car l'ordre ou la lecture/écriture est important.

Voici le code qui rend l'ordre correct lors de l'écriture/lecture des données vers/depuis le colis (voir également ce lien ):

public class FriendDetail implements Parcelable {

    private String full_name;
    private int privacy;

    public HeatFriendDetail(Parcel in) {
        this.full_name = in.readString();
        this.privacy = in.readInt();
    }

    public HeatFriendDetail() {

    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(this.full_name);
        dest.writeInt(this.privacy);
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public HeatFriendDetail createFromParcel(Parcel in) {
            return new HeatFriendDetail(in);
        }

        public HeatFriendDetail[] newArray(int size) {
            return new HeatFriendDetail[size];
        }
    };

    // GETTER SETTER//
}
31
Imtiyaz Khalani

J'ai reçu cette erreur uniquement dans la version apk, car le CREATEUR n'était pas public.

J'ai changé ça:

static final Parcelable.Creator<Station> CREATOR = new Parcelable.Creator<Station>() {

Pour ça :

public static final Parcelable.Creator<Station> CREATOR = new Parcelable.Creator<Station>() {
6
Nika Kurdadze

Je suis juste tombé sur ça.

J'avais une intuition et j'ai regardé dans mon fichier de mappage ProGuard.

Normalement, je déclare CREATOR comme ceci:

    public static final Parcelable.Creator<ClassA> CREATOR = 
            new Parcelable.Creator<ClassA>() {

qui apparaît dans le fichier de mappage comme ceci:

    Android.os.Parcelable$Creator CREATOR -> CREATOR

..except pour une classe, la classe signalée avec l'erreur. Je l'ai déclaré comme ceci:

    public static Creator<ClassB> CREATOR =
            new Creator<ClassB>() {

Et voilà:

    Android.os.Parcelable$Creator CREATOR -> a

Donc, si vous obtenez cette exception dans votre version de production, vérifiez votre fichier de mappage. Je pense que ProGuard est vraiment sensible à la façon dont CREATOR est déclaré lorsqu'il décide de ne pas le masquer.

4
kris larson

J'ai eu ce message d'erreur lorsque la classe CREATOR n'était pas statique

2
SpyZip

Si vous utilisez des règles proguard ajoutez cette ligne à votre proguard-rules.pro

-keepnames class * implements Android.os.Parcelable {
public static final ** CREATOR;

}

2
Arjun Othayoth