Java Parcelable 协议需要一个名为 CREATOR 的 Parcelable.Creator 对象(我确实有 CREATOR)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18548077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:56:50  来源:igfitidea点击:

Parcelable protocol requires a Parcelable.Creator object called CREATOR (I do have CREATOR)

javaandroideclipseparcelable

提问by Guy

I am trying to pass Parcelable data from one intent to another and this is the error I am getting:

我试图将 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

The thing is: I do have Parcelable.Creator object. I'll post the whole Parcelable code below:

问题是:我确实有 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];
    }

}

Is there somethin wrong with the CREATOR? The app crashes as soon as I click the button to start the next activity.

CREATOR 有什么问题吗?一旦我单击按钮开始下一个活动,应用程序就会崩溃。

This is how I "retrieve" Parcelable data in the second activity:

这就是我在第二个活动中“检索” Parcelable 数据的方式:

//global variable
ArrayList<Player> playersParceledData;

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

Also, this is how I put class objects to ParcelableArrayListExtra:

此外,这就是我将类对象放入 ParcelableArrayListExtra 的方式:

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

采纳答案by Imtiyaz Khalani

You are have different sequence when reading from Parcel than the one you write in.

从 Parcel 读取与写入时的顺序不同。

In writeToParcel()you are first putting String but in the HeatFriendDetail(Parcel in), you first read integer. It is not the correct way because the order or read/write matters.

writeToParcel()您首先放入 String 但在 中HeatFriendDetail(Parcel in),您首先读取整数。这不是正确的方法,因为顺序或读/写很重要。

Following is the code which makes correct order when writing/reading the data to/from Parcel (also see this link):

以下是在向/从 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//
}

回答by Biraj Zalavadia

Try this way

试试这个方法

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

回答by SpyZip

I had this error message when the CREATOR class was not static

当 CREATOR 类不是静态时,我收到此错误消息

回答by kris larson

Just ran into this.

刚碰到这个。

I had a hunch, and I looked in my ProGuard mapping file.

我有一种预感,我查看了我的 ProGuard 映射文件。

Normally I declare CREATOR like this:

通常我这样声明 CREATOR:

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

which shows up in the mapping file like this:

它显示在映射文件中,如下所示:

    android.os.Parcelable$Creator CREATOR -> CREATOR

..except for one class, the class that was reported with the error. I declared it like this:

..除了一类,报错误的类。我是这样声明的:

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

Lo and behold:

你瞧:

    android.os.Parcelable$Creator CREATOR -> a

So if you are getting this exception in your production release, check your mapping file. I think ProGuard is really sensitive to how CREATOR is declared when deciding not to obfuscate it.

因此,如果您在生产版本中遇到此异常,请检查您的映射文件。我认为 ProGuard 在决定不混淆它时对 CREATOR 的声明方式非常敏感。

回答by Nika Kurdadze

I received this error in release apk only, because the CREATOR was not public.

我仅在发布 apk 中收到此错误,因为 CREATOR 未公开。

I changed this :

我改变了这个:

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

To this :

对此:

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

回答by Arjun Othayoth

If you are using proguard rules add this line in to your proguard-rules.pro

如果您使用 proguard 规则,请将此行添加到您的 proguard-rules.pro

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

}

}