2012-01-27 62 views
8

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

这是我正在尝试完成的示例代码,但它不能编译,因为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>() 
     { 
      ... 
     } 
    } 
} 
+0

你可以看看到http://stackoverflow.com/questions/35923039/android-implementing-parcelable-inner-class这将帮助你。 – chaitanya 2016-06-03 17:24:15

+0

看看这个解决方案。这将帮助你http://stackoverflow.com/questions/35923039/android-implementing-parcelable-inner-class – chaitanya 2016-06-03 18:17:58

回答

3

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

+0

谢谢你的回应。是的,那将是理想的解决方案。但是,我必须与期望Foo.Bar的一些jni代码(我没有C++重新编译)进行交互(并且如果它获得Bar,则会崩溃)。 – MichaelL 2012-01-27 01:44:03

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]; 
     } 
    } 
} 
8

我最近遇到了同样的问题,使得内部类的静态在我的处境工作。

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

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

+0

当使用嵌套的parcelable类时,声明内部可分类为'static'。 – Eido95 2017-01-18 21:50:53

0

您的酒吧不必是可以发送的。您可以将条形字段与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; 
     } 
    } 
}