Запись списка разделяемых объектов в разделяемый объект

Я пытаюсь записать список объектов, подлежащих разделению, в объект, подлежащий разделению, но получаю сообщение об ошибке времени выполнения Java, говорящее: «Класс не найден при распаковке ...».

Логкэт

11-13 08:41:06.412: E/Parcel(791): Class not found when unmarshalling: com.firstandroidapp.EventMeta
11-13 08:41:06.412: E/Parcel(791): java.lang.ClassNotFoundException: com.firstandroidapp.EventMeta
11-13 08:41:06.412: E/Parcel(791):  at java.lang.Class.classForName(Native Method)
11-13 08:41:06.412: E/Parcel(791):  at java.lang.Class.forName(Class.java:204)
11-13 08:41:06.412: E/Parcel(791):  at java.lang.Class.forName(Class.java:169)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readParcelableCreator(Parcel.java:2091)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readParcelable(Parcel.java:2055)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readValue(Parcel.java:1971)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readListInternal(Parcel.java:2264)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readList(Parcel.java:1537)
11-13 08:41:06.412: E/Parcel(791):  at com.firstandroidapp.EventHolder.<init>(EventHolder.java:36)
11-13 08:41:06.412: E/Parcel(791):  at com.firstandroidapp.EventHolder$1.createFromParcel(EventHolder.java:17)
11-13 08:41:06.412: E/Parcel(791):  at com.firstandroidapp.EventHolder$1.createFromParcel(EventHolder.java:1)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readParcelable(Parcel.java:2062)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readValue(Parcel.java:1971)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Parcel.readMapInternal(Parcel.java:2255)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Bundle.unparcel(Bundle.java:223)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Bundle.getParcelable(Bundle.java:1170)
11-13 08:41:06.412: E/Parcel(791):  at android.content.Intent.getParcelableExtra(Intent.java:4501)
11-13 08:41:06.412: E/Parcel(791):  at com.firstandroidapp.AddSubjectFragment.onActivityResult(AddSubjectFragment.java:198)
11-13 08:41:06.412: E/Parcel(791):  at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:166)
11-13 08:41:06.412: E/Parcel(791):  at android.app.Activity.dispatchActivityResult(Activity.java:5322)
11-13 08:41:06.412: E/Parcel(791):  at android.app.ActivityThread.deliverResults(ActivityThread.java:3363)
11-13 08:41:06.412: E/Parcel(791):  at android.app.ActivityThread.handleSendResult(ActivityThread.java:3410)
11-13 08:41:06.412: E/Parcel(791):  at android.app.ActivityThread.access$1100(ActivityThread.java:141)
11-13 08:41:06.412: E/Parcel(791):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-13 08:41:06.412: E/Parcel(791):  at android.os.Looper.loop(Looper.java:137)
11-13 08:41:06.412: E/Parcel(791):  at android.app.ActivityThread.main(ActivityThread.java:5103)
11-13 08:41:06.412: E/Parcel(791):  at java.lang.reflect.Method.invokeNative(Native Method)
11-13 08:41:06.412: E/Parcel(791):  at java.lang.reflect.Method.invoke(Method.java:525)
11-13 08:41:06.412: E/Parcel(791):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-13 08:41:06.412: E/Parcel(791):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-13 08:41:06.412: E/Parcel(791):  at dalvik.system.NativeStart.main(Native Method)
11-13 08:41:06.412: E/Parcel(791): Caused by: java.lang.NoClassDefFoundError: com/firstandroidapp/EventMeta
11-13 08:41:06.412: E/Parcel(791):  ... 32 more
11-13 08:41:06.412: E/Parcel(791): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.firstandroidapp.EventMeta" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib]]
11-13 08:41:06.412: E/Parcel(791):  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)
11-13 08:41:06.412: E/Parcel(791):  at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
11-13 08:41:06.412: E/Parcel(791):  at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
11-13 08:41:06.412: E/Parcel(791):  ... 32 more

Насколько я понимаю, ошибка возникает при записи списка EventMeta в EventHolder.

Вот реализации как EventHolder, так и EventMeta.

EventHolder

public class EventHolder implements Parcelable {

    public List<EventMeta> mEMList = new ArrayList<EventMeta>();
    public Event mEvent;

    @SuppressWarnings("rawtypes")
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public EventHolder createFromParcel(Parcel in) {
            return new EventHolder(in); 
        }

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


    public EventHolder(List<EventMeta> mEMList, Event mEvent) {
        this.mEMList = mEMList;
        this.mEvent = mEvent;
    }

    public EventHolder(Parcel in){
        mEMList= new ArrayList<EventMeta>();
        in.readTypedList(mEMList, EventMeta.CREATOR);
        this.mEvent = in.readParcelable(null);
    }

    public int describeContents(){
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeTypedList(mEMList); 
        dest.writeParcelable(mEvent, flags);
    }
}

EventMeta

public class EventMeta implements Parcelable {

    long mEventMetaId;
    long mEventId;
    Date mStartDate;

    @SuppressWarnings("rawtypes")
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public EventMeta createFromParcel(Parcel in) {
            return new EventMeta(in);
        }

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

    public EventMeta(long mEventMetaId, long mEventId, Date mStartDate) {
        this.mEventMetaId = mEventMetaId;
        this.mEventId = mEventId;
        this.mStartDate = mStartDate;
    }

    public EventMeta(Parcel in) {
        this.mEventMetaId = in.readLong();
        this.mEventId = in.readLong();
        this.mStartDate = new Date(in.readLong());
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.mEventMetaId);
        dest.writeLong(this.mEventId);
        dest.writeLong(this.mStartDate.getTime());
    }

}

Что-то не так с моим кодом? Я дважды проверял все перед публикацией, но не мог найти ничего лишнего.

Обновлять ##

Я использовал ответ daneejela, и теперь проблема переместилась в класс под названием «Класс», что означает, что проблема частично решена.

Class расширяет `Event, и это выглядит так:

public class Class extends Event {  

    long mClassId;
    String mClassLocation;
    long mSubjectId;

    @SuppressWarnings("rawtypes")
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Class createFromParcel(Parcel in) {
            return new Class(in);
        }

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

    public Class(long mClassId, String location, long mSubjectId, long mEventId, int mEventPriority, String mEventTitle, String mEventNotes, long start, long end) {
        super(mEventId, mEventPriority, mEventTitle, mEventNotes, start, end);
        this.mClassId = mClassId;
        this.mClassLocation = location;
        this.mSubjectId = mSubjectId;
    }

    public Class(Parcel in){
        super(in);
        this.mClassId = in.readLong();
        this.mClassLocation = in.readString();
        this.mSubjectId = in.readLong();
    }

    public int describeContents(){
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeLong(this.mClassId);
        dest.writeString(this.mClassLocation);
        dest.writeLong(this.mSubjectId);
    }
}

Обновление 2

Мероприятие

public class Event implements Parcelable {

    long mEventId;
    int mEventPriority;
    String mEventTitle;
    String mEventNotes;
    long mEventStartTime;
    long mEventEndTime;

    @SuppressWarnings("rawtypes")
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Event createFromParcel(Parcel in) {
            return new Event(in); 
        }

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

    public Event(long id, int priority, String title, String notes, long start, long end) {
        this.mEventId = id;
        this.mEventPriority = priority;
        this.mEventTitle = title;
        this.mEventNotes = notes;
        this.mEventStartTime = start;
        this.mEventEndTime = end;
    }

    public Event(Parcel in){
        this.mEventId = in.readLong();
        this.mEventPriority = in.readInt();
        this.mEventTitle = in.readString();
        this.mEventNotes = in.readString();
        this.mEventStartTime = in.readLong();
        this.mEventEndTime = in.readLong();
    }

    public int describeContents(){
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.mEventId);
        dest.writeInt(this.mEventPriority);
        dest.writeString(this.mEventTitle);
        dest.writeString(this.mEventNotes);
        dest.writeLong(this.mEventStartTime);
        dest.writeLong(this.mEventEndTime);
    }
}

person Asaf    schedule 13.11.2013    source источник
comment
Есть ли какая-то особая причина, по которой вы должны использовать EventMeta? ArrayList уже можно разделить.   -  person Andrew Schuster    schedule 13.11.2013
comment
Что ты имеешь в виду? EventMeta содержит информацию, поэтому мне нужно ее использовать.   -  person Asaf    schedule 13.11.2013
comment
Прошу прощения, я имел в виду EventHolder. EventMeta выглядит нормально, но в вашем EventHolder кажется излишним писать целый класс только для того, чтобы связать один Event со списком EventMeta.   -  person Andrew Schuster    schedule 13.11.2013
comment
Хм... Можете ли вы опубликовать код события? (P.S. Изменится ли что-нибудь, если вы измените общедоступный статический финал Parcelable.Creator CREATOR = new Parcelable.Creator() на общедоступный статический финал Parcelable.Creator‹Class› CREATOR = new Parcelable.Creator‹Class›() ? )   -  person daneejela    schedule 13.11.2013
comment
@AndrewSchuster - Спасибо. Я думаю, что использование ArrayList облегчило бы задачу. Не знаю, почему я не подумал об этом раньше. При этом я хотел бы оставить EventHolder как есть, поскольку мое приложение далеко не готово, возможно, мне придется добавить больше полей в EventHolder в будущем. Тем не менее, я замечу для себя, что вернусь к этому, когда придет время. Большое спасибо за отличную идею! (P.S. Вы случайно не знаете, есть ли разница в производительности между этими двумя подходами?)   -  person Asaf    schedule 14.11.2013
comment
@daneejela - Это не сработало :(. Я добавил код для класса Event. Спасибо! :)   -  person Asaf    schedule 14.11.2013
comment
@xTCx Производительность, вероятно, не будет проблемой, но если вы планируете передавать этот материал между действиями, помните об ограничениях памяти! На самом деле вы не можете передать столько информации через Bundle. Ограничение составляет около 500 КБ.   -  person Andrew Schuster    schedule 14.11.2013
comment
@AndrewSchuster - я действительно собираюсь передать это как намерение. Это то же самое? К счастью, EventHolder ограничен примерно 7-8 EventMetas. Должно быть достаточно, не так ли? Я буду осторожен и протестирую перед выпуском приложения. Благодарю вас!   -  person Asaf    schedule 14.11.2013
comment
@xTCx Извините, да, я это и имел в виду. Надеюсь все будет в порядке, если вы не будете добавлять изображения.   -  person Andrew Schuster    schedule 14.11.2013


Ответы (2)


Попробуйте этот код

public class EventHolder implements Parcelable {
    public List mEMList = new ArrayList();
    public Event mEvent;

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public EventHolder createFromParcel(Parcel in) {
            return new EventHolder(in);
        }

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

    public EventHolder(List mEMList, Event mEvent) {
        this.mEMList = mEMList;
        this.mEvent = mEvent;
    }

    public EventHolder(Parcel in) {
        in.readList(mEMList, mEMList.getClass().getClassLoader());
        this.mEvent = in.readParcelable(mEvent.getClass().getClassLoader());
    }

    public int describeContents() {
        return 0XFE;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(mEMList);
        dest.writeParcelable(mEvent, describeContents());
    }
}

и у меня есть сомнения, что это событие можно разделить? Если не сделать это как посылки.

person android_dev    schedule 13.11.2013
comment
Спасибо. Event действительно можно разделить. Я пробовал ваше решение, но оно не работает. Та же ошибка. - person Asaf; 13.11.2013

Вы пробовали это (внутри EventHolder):

public class EventHolder implements Parcelable {

//...

public EventHolder(Parcel in){
    mEMList= new ArrayList<EventMeta>();
    in.readTypedList(mEMList, EventMeta.CREATOR);
    this.mEvent = in.readParcelable(null);
}

public int describeContents(){
    return 0;
}

public void writeToParcel(Parcel dest, int flags) {
    dest.writeTypedList(mEMList); 
    dest.writeParcelable(mEvent, flags);
}

}
person daneejela    schedule 13.11.2013
comment
Благодарю вас! Видимо, это частично решило проблему. Дело в том, что теперь я получаю ту же ошибку, но для класса с именем Class, который расширяет Event. Я обновляю свой основной пост кодом для класса. Не могли бы вы посмотреть на это? :D - person Asaf; 13.11.2013