Android 将 Parcelable 的子类写入另一个 Parcel

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12239343/
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-20 10:08:35  来源:igfitidea点击:

Write a sub class of Parcelable to another Parcel

androidparcelable

提问by user4o01

I have a class that implements Parcelableinterface:

我有一个实现Parcelable接口的类:

class A implements Parcelable {

}

I have another class Bthat contains an Aobject as an instance variable. In the writeToPacelinside class B, I want to write object Bto the Parcel:

我有另一个类B,它包含一个A对象作为实例变量。在writeToPacel内部类B,我想写对象BParcel

class B implements Parcelable{

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

How can I write and read it?

我怎样才能写和读它?

回答by confucius

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);

    }
}

if you want to read it use this

如果你想阅读它使用这个

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

回答by pablisco

A better way to handle this that avoids reflexion would be to simply call the static creator in the target type like this:

处理这个避免反射的更好方法是简单地调用目标类型中的静态创建者,如下所示:

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

and write it to the Parcelableusing this.amazingObject.writeToParcel(Parcel, int)

并将其写入Parcelable使用this.amazingObject.writeToParcel(Parcel, int)

Internally, when calling readParcelable(ClassLoader)this happens:

在内部,调用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);
}

As you can see the last call of that method is just calling the right Creatorbut inside readParcelableCreatorthere is a whole lot of reflexion that we can avoid by just calling it directly.

正如您所看到的,该方法的最后一次调用只是调用了右边,Creator但在内部readParcelableCreator有很多反射,我们可以通过直接调用它来避免。

This utility calls may be useful:

此实用程序调用可能很有用:

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

}

回答by Alison

The line:

线路:

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

should change to:

应该改为:

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

I encountered the same problem and did several Google search, many webpage or tutorial suggests we use A.class.getClassLoader()because we are casting to A, but actually it is WRONG because you will get a null value, we must use B.class.getClassLoader()because the codes are INSIDE class B. I just did not know why but it can get the correct A object in this way.

我遇到了同样的问题并做了几次谷歌搜索,许多网页或教程建议我们使用,A.class.getClassLoader()因为我们正在转换为 A,但实际上它是错误的,因为你会得到一个空值,我们必须使用,B.class.getClassLoader()因为codes are INSIDE class B. 我只是不知道为什么,但它可以通过这种方式获得正确的 A 对象。

Welcome to comment and verify!!

欢迎评论和验证!!