Подтвердить что ты не робот

Напишите дополнительный класс Parcelable для другого участка

У меня есть класс, реализующий интерфейс Parcelable:

class A implements Parcelable {

}

У меня есть еще один класс B, который содержит объект A как переменную экземпляра. В writeToPacel внутри класса B я хочу записать объект B в Parcel:

class B implements Parcelable{

    public void writeToParcel(Parcel dest, int flags) {
        dest.write ??? 
    }
}

Как я могу писать и читать?

4b9b3361

Ответ 1

class B implements Parcelable{
//lets assume you have A as a data member 

A obj;
public void writeToParcel(Parcel dest, int flags) {

        dest.writeParcelable(obj , flags);

    }
}

если вы хотите его прочитать, используйте этот

 obj = in.readParcelable(A.class.getClassLoader());

Ответ 2

Лучший способ справиться с этим, что позволяет избежать рефлексии, - просто вызвать статического создателя в целевом типе следующим образом:

this.amazingObject = AmazingObject.CREATOR.createFromParcel(in);

и записать его в Parcelable, используя this.amazingObject.writeToParcel(Parcel, int)

Внутренне, при вызове readParcelable(ClassLoader) это происходит:

public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
    Parcelable.Creator<T> creator = readParcelableCreator(loader);
    if (creator == null) {
        return null;
    }
    if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
        return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
    }
    return creator.createFromParcel(this);
}

Как вы можете видеть, последний вызов этого метода просто вызывает правый Creator, но внутри readParcelableCreator есть много отражения, которое можно избежать, просто называя его напрямую.

Эта утилита может быть полезна:

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

public class Parcels {

    public static void writeBoolean(Parcel dest, Boolean value) {
        dest.writeByte((byte) (value != null && value ? 1 : 0));
    }

    public static Boolean readBoolean(Parcel in){
        return in.readByte() != 0;
    }

    public static void writeParcelable(Parcel dest, int flags, Parcelable parcelable) {
        writeBoolean(dest, parcelable == null);
        if (parcelable != null) {
            parcelable.writeToParcel(dest, flags);
        }
    }

    public static <T extends Parcelable> T readParcelable(Parcel in, Parcelable.Creator<T> creator) {
        boolean isNull = readBoolean(in);
        return isNull ? null : creator.createFromParcel(in);
    }

}

Ответ 3

Строка:

obj = (A)in.readParcelable(A.class.getClassLoader());

должен измениться на:

obj = (A)in.readParcelable(B.class.getClassLoader());

Я столкнулся с одной и той же проблемой, и несколько поисков Google, многие веб-страницы или учебники подсказывают, что мы используем A.class.getClassLoader(), потому что мы отсылаем A, но на самом деле это НЕПРАВИЛЬНО, потому что вы получите нулевое значение, мы должны использовать B.class.getClassLoader() потому что codes are INSIDE class B. Я просто не знал, почему, но он может получить правильный объект A таким образом.

Добро пожаловать, чтобы прокомментировать и подтвердить!