2012-01-27 17 views
8

Ho bisogno di sapere come rendere una classe interna Parcelable in modo che gli oggetti del suo tipo possano essere passati tramite AIDL a un servizio remoto. Non riesco a trovare alcuna informazione su questo.Come rendere una classe interna Parcelable

Ecco il codice di esempio di ciò che sto cercando di realizzare, ma non viene compilato perché CREATOR nella classe Bar non può essere statico (ovvero perché si trova in una classe interna). Non riesco a rendere Bar una classe interiore statica e non riesco a spostare Bar fuori dalla classe Foo (altre dipendenze all'interno del sistema). Devo anche sapere come fare riferimento alla classe Bar da un file AIDL. Qualsiasi aiuto è molto apprezzato.

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

È possibile dare uno sguardo in http://stackoverflow.com/questions/35923039/android-implementing-parcelable-inner-class questo vi aiuterà. – chaitanya

+0

Dai un'occhiata a questa soluzione. Questo ti aiuterà http://stackoverflow.com/questions/35923039/android-implementing-parcelable-inner-class – chaitanya

risposta

3

La risposta è che una classe interiore può sempre essere fatta nella propria classe. Qualsiasi funzionalità la classe interna debba accedere dall'istanza della classe esterna o viceversa può sempre essere eseguita tramite un'interfaccia o un'API pubblica. Prova a rendere Bar la sua classe. Qualsiasi componente di Foo Bar necessiti dell'accesso, fornire passando l'istanza di Foo in Bar e implementando l'API appropriata.

+0

Grazie per la risposta. Sì, sarebbe la soluzione ideale. Tuttavia, devo interfacciarmi con qualche codice jni (per il quale non ho il C++ da ricompilare) che si aspetta un Foo.Bar (e si blocca se ottiene una barra). – MichaelL

1

Se la classe esterna mantiene un riferimento alle istanze di classe interni si potrebbe fare in questo modo:

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

recente ho incontrato lo stesso problema e rendere la classe interna statica lavorato nella mia situazione.

Ho letto perché questo avrebbe funzionato e avrebbe avuto più senso per me, quindi ho pensato di condividerlo. Una classe interna è una classe che è annidata all'interno di un'altra classe e ha un riferimento a un'istanza della sua classe contenente. Attraverso tale riferimento può accedere ai membri delle classi contenenti come se fosse la classe contenente stessa. Pertanto è associato a un'istanza della classe contenente e quindi non può avere membri statici (poiché non sarebbero associati alla classe contenente).

Dichiarare la classe nidificata come statica disaccoppia da un'istanza della classe contenitore e quindi può avere le proprie variabili statiche (e qualsiasi altra cosa possa avere una classe regolare). Ovviamente non sarà in grado di accedere ai membri della classe contenente.

+0

Dichiarare la classe parcelable interna come 'static' ha funzionato per me quando si utilizzano classi parcelable nidificate. – Eido95

0

La barra non deve essere parcelable. È possibile solo salvare i campi barra insieme ai campi Foo e ripristinare l'intero oggetto nel metodo createFromParcel(Parcel).

Ecco alcuni esempio di codice ribalta:

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