java - parcelabler - El protocolo parcelable requiere un objeto Parcelable.Creator llamado CREATOR(tengo CREATOR)
parcelable android studio (5)
Estoy tratando de pasar datos Parcelable de un intento a otro y este es el error que estoy recibiendo:
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 cosa es: tengo el objeto Parcelable.Creator. Voy a publicar todo el código parcelable a continuación:
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];
}
}
¿Hay algo mal con el CREADOR? La aplicación se bloquea tan pronto como hago clic en el botón para iniciar la siguiente actividad.
Así es como "recupero" datos Parcelable en la segunda actividad:
//global variable
ArrayList<Player> playersParceledData;
//This is in onCreate
playersData = getIntent();
playersParceledData = playersData.getParcelableArrayListExtra("parceledData");
Además, así es como pongo los objetos de clase en ParcelableArrayListExtra:
Player newPlayer = new Player(0, text);
playersParceledData.add(newPlayer);
zacniIgro.putParcelableArrayListExtra("parceledData", playersParceledData);
Recibí este error solo en la versión de lanzamiento, porque el CREADOR no era público.
Cambié esto:
static final Parcelable.Creator<Station> CREATOR = new Parcelable.Creator<Station>() {
A esto :
public static final Parcelable.Creator<Station> CREATOR = new Parcelable.Creator<Station>() {
Recibí este mensaje de error cuando la clase CREATOR no era estática
Solo me encontré con esto.
Tuve una corazonada, y busqué en mi archivo de mapeo ProGuard.
Normalmente declaro CREADOR así:
public static final Parcelable.Creator<ClassA> CREATOR =
new Parcelable.Creator<ClassA>() {
que se muestra en el archivo de mapeo como este:
android.os.Parcelable$Creator CREATOR -> CREATOR
..excepto para una clase, la clase que se informó con el error. Lo declaré así:
public static Creator<ClassB> CREATOR =
new Creator<ClassB>() {
He aquí que:
android.os.Parcelable$Creator CREATOR -> a
Entonces, si está obteniendo esta excepción en su versión de producción, verifique su archivo de mapeo. Creo que ProGuard es realmente sensible a cómo se declara CREATOR cuando decide no ofuscarlo.
Tienes una secuencia diferente al leer de Parcel que la que escribes.
En writeToParcel()
, primero está poniendo String pero en HeatFriendDetail(Parcel in)
, primero lee entero. No es la forma correcta porque el orden o la lectura / escritura es importante.
A continuación se muestra el código que establece el orden correcto al escribir / leer los datos a / desde Parcel (también vea este enlace ):
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//
}
Prueba de esta manera
// 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"));
}