如何使内部类Parcelable

时间:2012-01-27 00:27:37

标签: java android inner-classes parcelable aidl

我需要知道如何创建一个内部类Parcelable,以便其类型的对象可以通过AIDL传递给远程服务。我找不到任何关于此的信息。

这是我想要完成的示例代码,但它不能编译,因为Bar类中的CREATOR不能是静态的(即因为它在内部类中)。我不能让Bar成为一个静态的内部类,我不能将Bar移到Foo类之外(系统中的其他依赖项)。我还需要知道如何在AIDL文件中引用Bar类。非常感谢任何帮助。

public class Foo implements Parcelable
{
    private int a;

    public Foo()
    {
    }

    public Foo(Parcel source)
    {
        this.a = source.readInt();
    }

    public int describeContents()
    {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags)
    {
        dest.writeInt(this.a);
    }

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

    public class Bar implements Parcelable
    {
        private int b;

        public Bar()
        {
        }

        public Bar(Parcel source)
        {
            this.b = source.readInt();
        }

        public int describeContents()
        {
            return 0;
        }

        public void writeToParcel(Parcel dest, int flags)
        {
            dest.writeInt(this.b);
        }

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

4 个答案:

答案 0 :(得分:8)

我最近遇到了同样的问题,并且在我的情况下使内部类静态工作。

我读到了为什么这实际上会起作用,这对我来说更有意义,所以我想我会分享。内部类是嵌套在另一个类中的类,并且具有对其包含类的实例化的引用。通过该引用,它可以访问包含类的成员,就好像它是包含类本身一样。因此它绑定到包含类的实例,因此不能有静态成员(因为它们不会绑定到包含类)。

将嵌套类声明为静态将其与包含类的实例解耦,因此可以拥有自己的静态变量(以及常规类可以拥有的任何其他内容)。当然,它将无法访问包含类的成员。

答案 1 :(得分:3)

答案是内部类总是可以成为自己的类。无论内部类需要从outter类的实例访问什么功能,反之亦然,总是可以通过接口或公共API来完成。尝试让Bar成为自己的类。无论Foo Bar需要访问哪些组件,都可以将Foo实例传递给Bar并实现相应的API。

答案 2 :(得分:1)

如果你的外部类保留了对内部类实例的引用,你可以这样做:

public class OuterClass implements Parcelable
{
    private InnerClass reference;

    protected OuterClass( Parcel source )
    {
        this.reference = new InnerClass( source );
        // ...
    }

    @Override
    public void writeToParcel( Parcel destination, int flags )
    {
        reference.writeToParcel( destination, flags );
        // ...
    }

    public class InnerClass implements Parcelable
    {
        protected InnerClass( Parcel source )
        {
            // Read from your parcel.
        }

        @Override
        public void writeToParcel( Parcel destination, int flags )
        {
            // Write to your parcel.
        }
    }

    public static final Parcelable.Creator<OuterClass> CREATOR = new Creator<OuterClass>()
    {
         @Override
         public OuterClass createFromParcel( Parcel source )
         {
             return new OuterClass( source );
         }

         @Override
         public OuterClass[] newArray( int size )
         {
             return new OuterClass[size];
         }
    }
}

答案 3 :(得分:0)

您的酒吧不一定是Parcelable。您可以将条形字段与Foo字段一起保存,并在createFromParcel(Parcel)方法中恢复整个对象。

以下是一些代码示例:

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

public class Foo implements Parcelable {
    private int mFooData = 0;
    private Bar mBar;

    public Foo() {
    }

    protected Foo(Parcel in) {
        mFooData = in.readInt();

        // Reading Bar
        int barData = in.readInt();
        mBar = new Bar(barData);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mFooData);

        // Writing Bar
        dest.writeInt(mBar.getBarData());
    }

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

    public static final Creator<Foo> CREATOR = new Creator<Foo>() {
        @Override
        public Foo createFromParcel(Parcel in) {
            return new Foo(in);
        }

        @Override
        public Foo[] newArray(int size) {
            return new Foo[size];
        }
    };

    public class Bar {
        private int mBarData = 0;

        public Bar(int barData) {
            mBarData = barData;
        }

        public int getBarData() {
            return mBarData;
        }

        public void setBarData(int mBarData) {
            this.mBarData = mBarData;
        }
    }
}