Для протокола Parcelable требуется объект Parcelable.Creator, называемый CREATOR (у меня есть CREATOR)
Я пытаюсь передать Parcelable данные от одного намерения к другому, и это ошибка, которую я получаю:
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];
}
}
Что-то не так с CREATOR? Приложение аварийно завершает работу, как только я нажимаю кнопку, чтобы начать следующую операцию.
Вот как я "извлекаю" 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);
Ответы
Ответ 1
У вас другая последовательность при чтении из Parcel, чем та, в которой вы пишете.
В writeToParcel()
вы сначала помещаете String, но в HeatFriendDetail(Parcel in)
вы сначала читаете целое число. Это не правильный путь, потому что порядок или чтение/запись имеют значение.
Ниже приведен код, который устанавливает правильный порядок при записи/чтении данных в/из Parcel (также см. Эту ссылку):
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//
}
Ответ 2
Я получил эту ошибку только в выпуске apk, потому что CREATOR не был общедоступным.
Я изменил это:
static final Parcelable.Creator<Station> CREATOR = new Parcelable.Creator<Station>() {
Для этого:
public static final Parcelable.Creator<Station> CREATOR = new Parcelable.Creator<Station>() {
Ответ 3
Просто наткнулся на это.
У меня была догадка, и я посмотрел в файл сопоставления ProGuard.
Обычно я объявляю CREATOR следующим образом:
public static final Parcelable.Creator<ClassA> CREATOR =
new Parcelable.Creator<ClassA>() {
который отображается в файле сопоставления следующим образом:
android.os.Parcelable$Creator CREATOR -> CREATOR
.. за исключением одного класса, класса, о котором сообщалось с ошибкой. Я объявил следующее:
public static Creator<ClassB> CREATOR =
new Creator<ClassB>() {
Ло и вот:
android.os.Parcelable$Creator CREATOR -> a
Итак, если вы получаете это исключение в своей производственной версии, проверьте свой файл сопоставления. Я думаю, ProGuard действительно чувствителен к тому, как объявляется CREATOR при принятии решения не обфускации его.
Ответ 4
У меня возникло это сообщение об ошибке, когда класс CREATOR не был статическим
Ответ 5
Если вы используете правила proguard, добавьте эту строку в ваш proguard-rules.pro
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
Ответ 6
Попробуйте этот способ
// 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"));
}