2012-01-27 21 views
8

Tôi cần phải biết làm thế nào để làm cho một lớp bên trong Parcelable để các đối tượng của loại hình của nó có thể được truyền qua AIDL đến một dịch vụ từ xa. Tôi không thể tìm thấy bất kỳ thông tin nào về điều này.Làm thế nào để làm cho một lớp bên trong Parcelable

Đây là mã ví dụ về những gì tôi đang cố gắng thực hiện, nhưng nó không biên dịch vì CREATOR trong lớp Bar không thể tĩnh (tức là vì nó nằm trong lớp bên trong). Tôi không thể biến Bar thành một lớp bên trong tĩnh và tôi không thể di chuyển Bar ra ngoài lớp Foo (các phụ thuộc khác trong hệ thống). Tôi cũng cần phải biết làm thế nào tôi sẽ tham khảo các lớp học Bar từ bên trong một tập tin AIDL. Bất kỳ trợ giúp nào cũng được đánh giá rất cao.

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

Bạn có thể có một cái nhìn vào http://stackoverflow.com/questions/35923039/android-implementing-parcelable-inner-class này sẽ giúp bạn. – chaitanya

+0

Hãy xem giải pháp này. Điều này sẽ giúp bạn http://stackoverflow.com/questions/35923039/android-implementing-parcelable-inner-class – chaitanya

Trả lời

3

Câu trả lời là lớp bên trong luôn có thể được tạo thành lớp riêng. Bất cứ chức năng nào mà lớp bên trong cần truy cập từ thể hiện của lớp outter hoặc ngược lại đều có thể được thực hiện thông qua giao diện hoặc API công khai. Hãy thử biến Bar thành lớp riêng của mình. Bất cứ thành phần nào của Foo Bar cần truy cập, cung cấp bằng cách truyền thể hiện của Foo vào Bar và triển khai API thích hợp.

+0

Cảm ơn bạn đã phản hồi. Vâng, đó sẽ là giải pháp lý tưởng. Tuy nhiên, tôi có giao diện với một số mã jni (mà tôi không có C + + để biên dịch lại) đó là mong đợi một Foo.Bar (và treo nếu nó nhận được một Bar). – MichaelL

1

Nếu lớp bên ngoài của bạn giữ một tham chiếu đến các trường hợp lớp bên trong bạn có thể làm điều đó như thế này:

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

Gần đây tôi đã chạy vào cùng một vấn đề và làm cho lớp bên trong tĩnh làm việc trong hoàn cảnh của tôi.

Tôi đã đọc lý do tại sao điều này thực sự hiệu quả và điều đó có ý nghĩa hơn đối với tôi, vì vậy tôi nghĩ tôi sẽ chia sẻ. Một lớp bên trong là một lớp được lồng vào bên trong một lớp khác và có một tham chiếu đến một sự khởi tạo của lớp chứa của nó. Thông qua tham chiếu đó, nó có thể truy cập các thành viên chứa các lớp như thể nó là lớp chứa chính nó. Do đó nó được ràng buộc với một thể hiện của lớp chứa và do đó không thể có các thành viên tĩnh (vì chúng sẽ không bị ràng buộc với lớp chứa).

Khai báo lớp lồng nhau là tĩnh tách nó khỏi một thể hiện của lớp chứa, và do đó có thể có các biến tĩnh riêng (và bất kỳ biến nào khác mà một lớp thông thường có thể có). Tất nhiên nó sẽ không thể truy cập các thành viên của lớp chứa.

+0

Khai báo lớp có thể chuyển nhượng bên trong thành 'static' làm việc cho tôi khi sử dụng các lớp có thể đặt gói được lồng nhau. – Eido95

0

Thanh của bạn không phải là Bưu kiện. Bạn chỉ có thể lưu các trường Bar cùng với các trường Foo và khôi phục toàn bộ đối tượng trong phương thức createFromParcel(Parcel).

Dưới đây là một số ví dụ mã fore:

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