1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Abstrakte Klasse zu einem Remote Service senden...

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von Unicate, 23.02.2012.

  1. Unicate, 23.02.2012 #1
    Unicate

    Unicate Threadstarter Android-Experte

    Beiträge:
    473
    Erhaltene Danke:
    57
    Registriert seit:
    09.08.2010
    Hallo alle zusammen!

    Ich muss eine Abstrakte Klasse zu einem Remote Service senden können.

    Hier erstmal was ich bisher schon getan habe:

    Hier der Kopf der Klasse:
    Code:
    public abstract class AbstractClass implements Parcelable {
    
    Es gibt natürlich auch ein passendes *.aidl File:
    Code:
    package de.unicate.android.remoteservice.interfaces;
    
    parcelable AbstractClass;
    
    Das Problem hier ist eigentlich "nur" die statische variable CREATOR, welche jede Klasse implementiert haben muss, wenn sie Parcelable implementiert.

    Dazu habe ich der Abstrakten Klasse eine leere Variable gegeben.
    Code:
    public static Parcelable.Creator<? extends AbstractClass> CREATOR = null;
    
    Die Idee war, das die von "AbstractClass" abgeleitete Klasse, sowieso die Variable CREATOR implementieren muss. Quasi ein überladen, einer statischen Variable.

    Das funktionierte auch soweit ganz gut, bis ich aus dem Service einen RemoteService machte.

    Also mal zusammen gefasst:


    • In einem Lokalen Service funkioniert das
    • In einem Remote Service nicht.
    Ich brauche das dringend in einem Remote Service.


    Hat jemand eine Idee, wie ich das machen könnte?
     
  2. the_alien, 23.02.2012 #2
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Lass mich raten. Im RemoteService gibt es eine NullPointerException?
     
  3. Unicate, 23.02.2012 #3
    Unicate

    Unicate Threadstarter Android-Experte

    Beiträge:
    473
    Erhaltene Danke:
    57
    Registriert seit:
    09.08.2010
    Naja, eigentlich "nur" im Connector, aber das ist sicher das was du meinst.

    Code:
    02-23 15:43:50.055: E/AndroidRuntime(16239): Caused by: java.lang.NullPointerException
    02-23 15:43:50.055: E/AndroidRuntime(16239):     at android.os.Parcel.readException(Parcel.java:1333)
    02-23 15:43:50.055: E/AndroidRuntime(16239):     at android.os.Parcel.readException(Parcel.java:1281)
    02-23 15:43:50.055: E/AndroidRuntime(16239):     at de.unicate.android.backgroundservice.BackgroundServiceConnector$Stub$Proxy.addAbstractClass(BackgroundServiceConnector.java:165)
    
    Gibt es eine Lösung für das Problem?
     
  4. the_alien, 23.02.2012 #4
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Das Problem ist, dass hier wirklich über Prozessgrenzen hinweg gearbeitet wird, dass heißt hier wird dein Objekt wirklich serialisiert und Parcelable wird wirklich benötigt. Bei einem lokalen Service ist das nicht nötig, da alles noch in der gleichen DalvikVM läuft.

    Das Objekt möchte sich jetzt wiederherstellen und muss dafür auf den CREATOR zugreifen. Da überhaupt nicht bekannt ist welche konkrete Implementierung vorhanden ist wird der CREATOR der abstrakten Klasse benutzt, der ist aber leider null.
    Du wirst dir -denke ich- einen Creator für die abstrakte Klasse erstellen müssen, der auch checkt welche konkrete Implementierung habe ich hier vorliegen. D.h. das müsste beim zerlegen des Objektes auch gespeichert werden. Dann muss der Creator der abstrakten Klasse den Creator der konkreten Implementierung aufrufen.
     
  5. Unicate, 23.02.2012 #5
    Unicate

    Unicate Threadstarter Android-Experte

    Beiträge:
    473
    Erhaltene Danke:
    57
    Registriert seit:
    09.08.2010
    Die Idee hatte ich auch schon verfolgt.

    Hier noch eine Frage:

    Angenommen, meine Abstrakte Klasse speichert jetzt ein Class object, mit welchem sie feststellen könnte, um welche klasse es sich handelt. Wie kann ich auf statische Variablen einer Klasse zugreifen, von der ich "nur" das Class Object habe?

    Oder anders:

    Wie kann ich statische Methoden oder Variablen einer Klasse aufrufen, von der ich nur das Class Object habe?
     
    Zuletzt bearbeitet: 23.02.2012
  6. the_alien, 23.02.2012 #6
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Du könntest ja den Klassennamen speichern oder einfach einen int Wert. Ganz popelig (ohne Reflection) könntest du dann sowas machen
    Code:
    Creator creator;
    switch(meineKlassenID) {
    case 1:
        creator = MeineKonkreteKlasseEins.CREATOR;
        break;
    case 2:
        creator = MeineKonkreteKlasseZwei.CREATOR;
        break;
    }
     
  7. Unicate, 23.02.2012 #7
    Unicate

    Unicate Threadstarter Android-Experte

    Beiträge:
    473
    Erhaltene Danke:
    57
    Registriert seit:
    09.08.2010
    Eben das wollt ich nicht, weil damit die Dynamik flöten geht.
     
  8. the_alien, 23.02.2012 #8
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Dann über Reflection.

    Code:
    public MeineAbstrakteKlasse createFromParcel(Parcel in) {
        String className = in.readString()
        Class clazz = Class.forName(className);
        Creator creator = (Creator)clazz.getDeclaredField("CREATOR").get(clazz);
        return creator.createFromParcel(in);
    }
    PS: Ausgehend davon, dass das erste im Parcel Objekt der Name der Klasse ist.
     
    Unicate bedankt sich.
  9. Unicate, 23.02.2012 #9
    Unicate

    Unicate Threadstarter Android-Experte

    Beiträge:
    473
    Erhaltene Danke:
    57
    Registriert seit:
    09.08.2010
    Ich les deine Nachricht erst jetzt, war schon von allein drauf gekommen. Das Stichwort Reflection hatte mir gefehlt.

    Das funktioniert 1a.

    Danke!


    Für andere mit dem selben Problem:

    Wenn man das so macht wie the_alien schrieb, muss man noch darauf achten, das die Klasse, welche die abstrakte erweitert in der Methode "writeToParcel" als erstes den Canonialen Namen der Klasse in das (?) Parcel Objekt schreibt.
     
  10. the_alien, 23.02.2012 #10
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Gerne :)
     

Diese Seite empfehlen