9
votes

Comment faire une classe intérieure parcelable

J'ai besoin de savoir comment faire une classe interne parclable de sorte que les objets de son type puissent être passés via AIDL à un service distant. Je ne trouve aucune information à ce sujet.

Voici exemple de code de ce que j'essaie d'accomplir, mais cela ne compile pas car le créateur de la classe de barres ne peut pas être statique (c'est-à-dire parce qu'il est dans une classe intérieure). Je ne peux pas faire de barre une classe intérieure statique et je ne peux pas déplacer la barre à l'extérieur de la classe FOO (autres dépendances du système). J'ai aussi besoin de savoir comment je voudrais faire référence à la classe de barres dans un fichier AIDL. Toute aide est grandement appréciée. P>

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>()
        {
            ...
        }
    }
}


2 commentaires

Vous pouvez jeter un coup d'œil à Stackoverflow.com/questions/35923039 / ... Cela vous aidera.


Jetez un coup d'œil à cette solution. Cela vous aidera Stackoverflow.com/Questtions/35923039/...


4 Réponses :


3
votes

La réponse est qu'une classe intérieure peut toujours être faite dans sa propre classe. Quelle que soit la fonctionnalité, la classe interne doit avoir accès à partir de l'instance de la classe wastter ou de Vise Versa peut toujours être effectuée via une interface ou une API publique. Essayez de faire une barre sa propre classe. Quels que soient les composants de FOO Bar ayant besoin d'accéder à, en passant l'instance de FOO dans la barre et implémentez l'API appropriée.


1 commentaires

Merci pour votre réponse. Oui, ce serait la solution idéale. Cependant, je dois m'interfacer avec certains code JNI (pour lequel je n'ai pas le C ++ à recompiler) qui attend un FOO.bar (et se bloque s'il reçoit une barre).



1
votes

Si votre classe extérieure conserve une référence aux instances de la classe interne, vous pouvez le faire comme ceci:

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


0 commentaires

8
votes

J'ai récemment couru dans le même problème et que la classe intérieure de la classe interne a travaillé dans ma situation.

Je lisais pourquoi cela fonctionnerait réellement et cela aurait plus de sens pour moi, alors je pensais que je partagerais. Une classe intérieure est une classe imbriquée à l'intérieur d'une autre classe et a une référence à une instanciation de sa classe contenant. À travers cette référence, il peut accéder aux membres contenant des classes comme s'il s'agissait de la classe contenant elle-même. Par conséquent, il est lié à une instance de la classe contenant et ne peut donc pas avoir des membres statiques (puisqu'ils ne seraient pas liés à la classe contenant).

Déclarant la classe imbriquée en tant que statique le découle à partir d'une instance de la classe contenant, et peut donc avoir ses propres variables statiques (et quelle que soit l'autre classe ordinaire). Bien sûr, il ne sera pas en mesure d'accéder aux membres de la classe contenant.


1 commentaires

Déclaration de la classe de cols intérieure en tant que statique a travaillé pour moi lors de l'utilisation de classes contrattables imbriquées.



1
votes

Votre barre ne doit pas être contractée. Vous pouvez simplement enregistrer des champs de bar avec FOO champs et restaurer l'objet entier dans Createfromparcel (parcelle) Code> Méthode.

Voici un code précédent: P>

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


0 commentaires