Abstrakte Klasse zu einem Remote Service senden...

U

Unicate

Erfahrenes Mitglied
57
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?
 
Lass mich raten. Im RemoteService gibt es eine NullPointerException?
 
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?
 
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.
 
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:
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;
}
 
Eben das wollt ich nicht, weil damit die Dynamik flöten geht.
 
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.
 
  • Danke
Reaktionen: Unicate
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.
 
Gerne :)
 

Ähnliche Themen

Jansenwilson
Antworten
1
Aufrufe
760
swa00
swa00
S
Antworten
0
Aufrufe
592
Sergio13
S
Zurück
Oben Unten