ClassCastException при попытке выполнить readParcelable в пользовательском массиве объектов

Я пытаюсь реализовать Parcelable вместо Serializble, поскольку он должен быть более эффективным. Из моей MainActivity я хочу передать объект сообщения другому действию, мой класс Message содержит другие классы. Если я справлюсь с этой одной ошибкой, я уверен, что столкнусь с гораздо большим количеством из них, но прямо сейчас, когда я пытаюсь запустить свое приложение, я получаю

Это мой класс сообщений:

import java.util.ArrayList;

import android.os.Parcel;
import android.os.Parcelable;

public class Message implements Parcelable {

    int id;
    int space_id;
    String text;
    String html;
    String created_at;
    int[] comments;
    boolean is_liked;
    int[] liked_by;
    int[] starred_by;
    boolean is_starred;
    boolean is_followed;
    int[] followed_by;
    ArrayList<AttachmentsData> attachments;
    String url;
    int[] tags;
    boolean is_system;

    public User created_by;
    public Permissions persmissions;
    public Embed embed;
    public Tokens[] tokens;


    /** Parcelable **/
    public Message(Parcel in) {
        readFromParcel(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) { 
        dest.writeInt(id);
        dest.writeInt(space_id);
        dest.writeString(text);
        dest.writeString(html);
        dest.writeString(created_at);
        dest.writeIntArray(comments);
        dest.writeInt(is_liked ? 1 : 0);
        dest.writeIntArray(liked_by);
        dest.writeIntArray(starred_by);
        dest.writeInt(is_starred ? 1 : 0);
        dest.writeInt(is_followed ? 1 : 0);
        dest.writeIntArray(followed_by);
        dest.writeList(attachments);
        dest.writeString(url);
        dest.writeIntArray(tags);
        dest.writeInt(is_system ? 1 : 0);

        dest.writeParcelable(created_by, flags);
        dest.writeParcelable(persmissions, flags);
        dest.writeParcelable(embed, flags);
        dest.writeParcelableArray(tokens, flags);
    }

    private void readFromParcel(Parcel in) {
        id = in.readInt();
        space_id = in.readInt();
        text = in.readString();
        html = in.readString();
        created_at = in.readString();
        //in.readIntArray(comments);
        comments = in.createIntArray();
        is_liked = in.readInt() == 0;
        //in.readIntArray(liked_by);
        liked_by = in.createIntArray();
        //in.readIntArray(starred_by);
        starred_by = in.createIntArray();
        is_starred = in.readInt() == 0;
        is_followed = in.readInt() == 0;
        //in.readIntArray(followed_by);
        followed_by = in.createIntArray();
        in.readList(attachments, AttachmentsData.class.getClassLoader());
        url = in.readString();
        //in.readIntArray(tags);
        tags = in.createIntArray();
        is_system = in.readInt() == 0;

        created_by = in.readParcelable(User.class.getClassLoader());
        persmissions = in.readParcelable(Permissions.class.getClassLoader());
        embed = in.readParcelable(Embed.class.getClassLoader());
        tokens = in.readParcelable(Tokens.class.getClassLoader();
    }   

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

        public Message createFromParcel(Parcel in) {
            return new Message(in);
        }

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



    /** Getters and setters, I'll spare you these **/

 }

И это ошибка, которую я получаю:

ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: main java.lang.RuntimeException: невозможно запустить действие ComponentInfo {com.example.incentive / com.example.incentive.Comments}: java.lang.ClassCastException: android.os.Parcelable [] нельзя преобразовать в com. example.incentive.messagemodel.Tokens [] в android.app.ActivityThread.performLaunchActivity (ActivityThread.java:1967) в android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:1992) в android.app.ActivityThread.access $ 600 (ActivityThread .java: 127) в android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1158) в android.os.Handler.dispatchMessage (Handler.java:99) в android.os.Looper.loop (Looper.java: 137) в android.app.ActivityThread.main (ActivityThread.java:4441) в java.lang.reflect.Method.invokeNative (собственный метод) в java.lang.reflect.Method.invoke (Method.java:511) в com .android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:784) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:551) a t dalvik.system.NativeStart.main (собственный метод) Вызвано: java.lang.ClassCastException: android.os.Parcelable [] не может быть преобразован в com.example.incentive.messagemodel.Tokens [] в com.example.incentive. messagemodel.Message.readFromParcel (Message.java:94) в com.example.incentive.messagemodel.Message. (Message.java:35) в com.example.incentive.messagemodel.Message $ 1.createFromParcel (Message.java:100) в com.example.incentive.messagemodel.Message $ 1.createFromParcel (Message.java:1) в android.os.Parcel.readParcelable (Parcel.java:1992) в android.os.Parcel.readValue (Parcel.java:1854) в android.os.Parcel.readMapInternal (Parcel.java:2094) в android.os.Bundle.unparcel (Bundle.java:223) в android.os.Bundle.getParcelable (Bundle.java:1158) в com.example. стимул.Comments.onCreate (Comments.java:67) в android.app.Activity.performCreate (Activity.java:4465) в android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1049) в android.app.ActivityTh read.performLaunchActivity (ActivityThread.java:1931) ... еще 11

Я думаю, что актуальным сейчас является:

Вызвано: java.lang.ClassCastException: android.os.Parcelable [] не может быть преобразован в com.example.incentive.messagemodel.Tokens [] в com.example.incentive.messagemodel.Message.readFromParcel (Message.java:94)

Так что, наверное, я делаю это неправильно: tokens = in.readParcelable (Tokens.class.getClassLoader ();

Вот мой класс токенов:

import android.os.Parcel;
import android.os.Parcelable;

public class Tokens implements Parcelable {

    String type;
    String value;
    int start;
    int end;


    /** Parcelable related **/
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(type);
        dest.writeString(value);
        dest.writeInt(start);
        dest.writeInt(end);
    }

    private Tokens(Parcel in) {
        type = in.readString();
        value = in.readString();
        start = in.readInt();
        end = in.readInt();
    }

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

        public Tokens createFromParcel(Parcel in) {
            return new Tokens(in);
        }

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


    /** Getters and setters **/ 
}

Я искал весь день и не могу найти, как это сделать правильно. Кто-нибудь знает?


person Phoebe    schedule 03.12.2013    source источник


Ответы (2)


Используйте writeTypedArray и readTypedArray для чтения и записи вашего массива в посылку

Читать

tokens = in.createTypedArray(Tokens.CREATOR);

Писать

in.writeTypedArray(tokens, flags);
person Matthew Mcveigh    schedule 03.12.2013
comment
Это сработало! Большое спасибо, хороший способ завершить день! : D - person Phoebe; 03.12.2013
comment
Я сделал это, и это работает, спасибо. Я просто не понимаю, для чего нужен readParcelable, если createTypedArray на самом деле предназначен для чтения parcelable! - person clocksmith; 01.03.2015
comment
@clocksmith Я считаю, что readParcelable предназначен для чтения одного значения - person Matthew Mcveigh; 03.03.2015

попробуй это...

заменять

 tokens = in.readParcelable(Tokens.class.getClassLoader();

с участием

 tokens = in.readParcelableArray(Tokens.class.getClassLoader());

вы пишете Parcelable Array, но читаете его как Parcelable

person Gopal Gopi    schedule 03.12.2013
comment
Я пробовал это, но это не позволяет мне скомпилировать, я получаю несоответствие типов: невозможно преобразовать из Parcelable [] в токены [] @Gopal Rao - person Phoebe; 03.12.2013
comment
@Phoebe добавить приведение к Tokens [] .... like tokens = (Tokens []) in.readParcelableArray (Tokens.class.getClassLoader ()); - person Gopal Gopi; 03.12.2013
comment
@ Gopal Rao Я тоже пробовал это, и хотя это позволяет мне скомпилировать и запустить приложение, все равно вылетает с ошибкой в ​​моем исходном посте. 12-03 15: 52: 45.978: E / AndroidRuntime (6672): Вызвано: java.lang.ClassCastException: android.os.Parcelable [] не может быть преобразован в com.example.incentive.messagemodel.Tokens [] - person Phoebe; 03.12.2013