2013-08-31 1 views
18

Я пытаюсь передать Parcelable данные от одного намерения к другому, и это ошибка я получаю:Parcelable протокол требует объект Parcelable.Creator под названием CREATOR (у меня есть CREATOR)

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 

Дело в том, : У меня есть объект Parcelable.Creator. Я выложу весь Parcelable код ниже:

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

} 

Есть ли что-нибудь неправильно с СОЗДАТЕЛЯМИ? Приложение аварийно завершает работу, как только я нажимаю кнопку, чтобы начать следующую операцию.

Это, как я «извлечь» Parcelable данные во второй деятельности:

//global variable 
ArrayList<Player> playersParceledData; 

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

Кроме того, это, как я ставлю объекты класса в ParcelableArrayListExtra:

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

Я рекомендовал использовать ArrayList > потому что оно не требует, чтобы преобразовать вы можете легко переносить между различными видами деятельности с использованием getSeriasableExtra(). Поскольку я вижу ваш код, у вас нет каких-либо сложных данных для хранения, поэтому нет смысла создавать специальный POJO для хранения. –

+0

@BirajZalavadia не могли бы вы дать мне быстрый пример того, как мой код будет выглядеть с помощью HashMap? Я никогда не использовал это раньше, и я не могу понять, как использовать его из официальных документов. – Guy

+0

Ваш класс 'player' не объявляет статический член' CREATOR'. Он объявляет только реализацию класса Creator ('MyCreator'). Помимо исправления последовательности, вам нужно добавить член 'CREATOR' в' player'. – Les

ответ

27

Вы имеете другую последовательность когда считая с Парселя, чем тот, который вы пишете.

В writeToParcel() вы сначала помещаете String, но в HeatFriendDetail(Parcel in), вы fi rst read integer. Это не так, потому что порядок или чтение/запись имеют значение.

Ниже приводится код, который делает правильный порядок при записи/чтения данных в/из посылок (также см this link):

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// 
} 
+0

Я сделал это, но я все равно получаю ту же ошибку – Guy

+0

, какая ошибка ..? –

+0

java.lang.RuntimeException: Невозможно запустить Activity ComponentInfo {com.matejsoftware.cardscoretracker/com.matejsoftware.cardscoretracker.Igra}: android.os.BadParcelableException: для протокола Parcelable требуется объект Parcelable.Creator, называемый CREATOR на классе com.matejsoftware. cardscoretracker.Novaigra $ Игрок – Guy

-1

Попробуйте этот путь

// create List of player 
     ArrayList<HashMap<String, String>> players = new ArrayList<HashMap<String, String>>(); 

     //create Player 

     HashMap<String, String> player = new HashMap<String, String>(); 
     player.put("score", "20");//replace 20 with your score variable 
     player.put("name", "Biraj");//replace Biraj with your name variable 

     // Add to arraylist 

     players.add(player); 

     // pass to intent 

     Intent i; 
     i.putExtra("PLAYERS", players); 

     // read From intent 

     ArrayList<HashMap<String, String>> playerFromintent = (ArrayList<HashMap<String, String>>) getIntent().getSerializableExtra("PLAYERS"); 

     // read from ArrayList 

     for (HashMap<String, String> hashMap : playerFromintent) { 
      System.out.println("Name : " + hashMap.get("name")); 
      System.out.println("Score : " + hashMap.get("score")); 
     } 
1

Я имел это сообщение об ошибке, когда класс CREATOR не был статическим

2

Просто наткнулся на это.

У меня была догадка, и я заглянул в файл сопоставления ProGuard.

Обычно я объявляю CREATOR, как это:

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

, который показывает в файле отображения, как это:

android.os.Parcelable$Creator CREATOR -> CREATOR 

..except для одного класса, класса, который сообщается с ошибкой , Я объявил это так:

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

глядь:

android.os.Parcelable$Creator CREATOR -> a 

Так что, если вы получаете это исключение в вашем релизе производства, проверьте файл отображения. Я думаю, что ProGuard действительно чувствителен к тому, как объявляется CREATOR при принятии решения не обфускации его.

4

Я получил эту ошибку только в выпуске apk, потому что CREATOR не был общедоступным.

Я изменил это:

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

Для этого:

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