Abstrakte Methoden verschachteln

D

Duckemai

Fortgeschrittenes Mitglied
6
Hallo zusammen,

ich habe eine Frage eher für einen Java-Spezi.
Ich versuche gerade für ein App eine abstrakte Methode innerhalb einer anderen abstrakten Methode aufzurufen. Die Methoden kommen aus jeweils unterschiedlichen .jar-Files.

Das ganze sieht so aus

@Override
public void ersteAbstMethode(boolean eingang) {
if (eingang) {//tue etwas}
else {
new com.test.bla.einListener() {
@Override
public void zweiteAbstMethode(int x){.....}
};//Listener
}//else
}//ersteAbstMethode

Wohlgemerkt: Die beiden Methoden kommen aus unterschiedlichen .jar-Files und haben nichts miteinander zu tun.

Grundsätzlich läuft das. Wenn das Programm aber in den else-Zweig geht, dann überspringt es die zweiteAbstMethode. Ich vermute, dass ich hier noch den Listener deklarieren muss, da ja durch die Zeile new... ein Listener gefordert wird.
Wenn ich die Methode auslagere, dann wird sie wie folgt per Listener in der onCreate erfolgreich aufgerufen:
MeineKlasse meinObjekt.setTestListener(this);

Weiß jemand, wie eine Deklaration des Listeners in dieser Verschachtelung in etwa aussehen müsste :confused2:

Vielen Dank
Duckemai
 
Ich glaube so wie du es beschrieben hast, stimmt alles auch (es ist etwas irreführend). Erstmal hast du zwei Methoden, die du deklarierst, ob nun von einem Interface oder einer abstrakten Klasse sei mal dahingestellt. In der ersten Methode erzeugst du ein neues Listenerobjekt, wenn ich das richtig bei dir verstanden habe. Du legst dabei eine innere Klasse an und in dieser inneren Klasse wird die Methode deklariert.

Daher ist es auch logisch, dass beim Aufruf der ersten Methode, die Methode der inneren Klasse nicht automatisch aufgerufen wird. Du musst einem Objekt den Listener zuweisen oder die Methode von dem erzeugten Objekt explizit aufrufen.

Ich hoffe das war etwas verständlich ^^
 
  • Danke
Reaktionen: Duckemai
Ich vermute zu wissen was Du meinst :lol:

Habe es nun so versucht:

...
else {
meinObjekt.setTestListener(
new com.test.bla.einListener() {
@Override
public void zweiteAbstMethode(Objekt x){.....}
});//Listener
}//else
}//ersteAbstMethode

Zwar habe ich keine Fehlermeldung, doch läuft er wieder über die abstrakte Methode 'zweiteAbstMethode' hinweg, in die er eigentlich hineinlaufen müsste.

Siehst Du vielleicht noch einen Fehler?
 
Zuletzt bearbeitet:
Nein, da ist kein Fehler ^^ Ich glaube du hast das Konzept noch nicht ganz begriffen. Listener sind zum "Abhören" da. Sie "beobachten" ein Objekt bzw. hören ihm zu. Irgendwann wird ein Event gefeuert und dann reagieren alle Listener, die im Objekt registriert sind und auf das Event warten.

Beispiel: Ein Button hat einen OnClickListener. Ich erzeuge den Button und füge den Listener hinzu. Irgendwann wird auf den Button gedrückt, dafür wird ein Event gefeuert und der Listener reagiert darauf entsprechend den Methoden, wie du sie implementierst.

In deinem Beispiel heißt das: Du hast das Objekt meinObjekt und fügst ihm einen Listener hinzu. Da diese Klasse von dem Listener abstrakt oder ein Interface ist, müssen die abstrakten Methoden noch implementiert werden. Du erzeugst eine innere Klasse. Das ist vollkommen üblich so. Allerdings wird die implementierte Methode von dem Listener noch nicht aufgerufen, da meinObjekt auf ein Event wartet. Wird das Event gefeuert, reagiert der Listener darauf und die Methode zweiteAbstMethode wird aufgerufen.

Jetzt verstanden? ^^

Edit: http://de.wikipedia.org/wiki/Observer_%28Entwurfsmuster%29 Kurzer Artikel dazu. Im Web findest du noch genug weitere Informationen dazu.
 
  • Danke
Reaktionen: Duckemai
Das auslösende Ereignis von dem Du spricht, wird automatisch durch den Listener geworfen (Oder von wem auch immer) Denn wenn ich die Methode 'zweiteAbstMethode' nicht verschachtel und den Listener gleich oben in der Klasse implementiere:

public class meineKlasse extends Activity implements einListener{...

dann wird die abstrakte Klasse immer durchlaufen. Beziehungsweise sind es fünf, von der mind. eine durchlaufen wird. Bei der Verschachtelung geht das aber leider nicht. Weiß nicht warum. Wie Du schon sagtest ist es vom Prinzip her eigentlich richtig. Der Listener ist in diesem Fall nicht von einem Button oder ähnlichem abhängig. Es geht dabei um ein Werbebanner, das mittels der Methoden entweder neu generiert wird, oder aber die Methode noAdAvailable durchläuft.
 
Tut mir Leid, da kann ich dir aber nicht weiter helfen, weil ich nur im Dunkeln raten kann. Entweder das Event wird vor dem registrieren des Listeners geworfen oder du verknüpfst das falsche Element? Ich weiß es nicht.

Oder eine Idee hätte ich noch: fügst du in der onCreate(..) Methode den Listener hinzu? Da vermute ich nämlich, dass das Event schon eher gefeuert wird.
 
  • Danke
Reaktionen: Duckemai
Ich vermute ebenfalls, dass das Event zu früh aufgerufen wird. Den Listener habe ich aber nur in der Verschachtelung stehen. Daran dürfte es also nicht liegen. Wenn ich die Verschachtelung aufgebe, dann schreibe ich den Listener natürlich in die onCreate und alles funktioniert.

Schade. Ich weiß auch nicht wie ich das Problem eingrenzen soll. Selbst wenn ich wüßte an welcher Stelle das Event geworfen wird, wüsste ich nicht, wie ich das verhindern könnte. Aus dem Source-Code scheint es nicht zu kommen. Da benutze ich außerhalb der Verschachtelung fast gar nichts mehr zu diesem Thema. Allerdings lege ich das Objekt 'meinObjekt' schon bei Programmstart in der Klasse an. Vielleicht ist das sogar schon zu früh. Weiß aber nicht, wo ich es sonst tun sollte.
Vielleicht fällt Dir dazu noch etwas ein?

Nichtsdestoweniger vielen Dank und Gruß
Duckemai
 
Zuletzt bearbeitet:
Naja, wenn das mit dem "implements" funktioniert, warum benutzt du nicht das?!

Wenn das nicht deine erste Activity von der App ist, dann kann man das Objekt auch schon eher anlegen und den Listener verknüpfen.

Es wäre natürlich sehr hilfreich, wenn du wüsstest, woher das Event kommt. An irgendeiner Stelle wird es ja geworfen und das kann nicht der Zufall sein.
 
Wenn ich implements benutze, dann muss ich auch in dieser Klasse die abstrakten Methoden anlegen, die dann durch welchen Event auch immer alle 30 Sekunden angesprochen werden. Diese möchte ich aber nur dann aufrufen, wenn die abstrakten Methoden des anderen jar-Files keinen AdBanner gefunden haben. Daher meine Idee zu verschachteln und eben diese abstrakte Methoden nur aufzurufen, wenn eine Kontrollstruktur an entsprechender Stelle (also bei: else) den Aufruf zulässt und dort den Listener starten. Wobei ich dann wahrscheinlich den Listener auch wieder stoppen müsste...
 
Naja also irgendwie klingt das alles bissel komisch und kann sicher effizienter umgesetzt werden. Aber das einfachste wir jetzt sein: benutze implements und einen boolean Wert. Und in der Methode vom Listener guckst du erst, ob der boolean Wert true ist, ansonsten soll er nichts machen.

Listener sollte man eigentlich auch wieder entfernen können. Weiß aber gerade nicht die Methode.
 
In der Methode des Listeners einen Boolean benutzen?
Wenn ich den Listener per implements benutze, dann ist das doch eine vorgefertigte Methode. Wie soll ich dort noch ein boolean reinhängen, bzw mit welchem Wert soll ich ihn befüllen. Der Boolean wird ja vom Listener nicht durchlaufen? Der Listener sieht einfach so aus:

AdbannerObjekt.setAdViewListener(this);

Wenn ich aber meinen eigenen Listener nehme, dann kann ich implements nicht benutzen, da der Aufruf im Listener selbst erfolgt
...AdbannerObjekt.setTestListener(
new com.test.bla.einListener() {...});

Ja, das geht bestimmt einfacher. Und vor allem professioneller. Eigentlich will ich ja nur 2 Werbebanner parallel laufen lassen. Ist der eine nicht erreichbar, wird der andere gezeigt und umgekehrt. Das wurde bestimmt schon mal programmiert. Selbst bekomme ich das wohl nicht hin.
 
class Test extends Activity implements Listener {

private boolean check = true;

public void methodeVomListener(...) {

if (check) {
check = false;
Mehtode....;
}

}

}


So in der Art war das gemeint.
 
Ja ok, Du meinst die abstrakten Methoden des Listeners. In der könnte ich versuchen eine Logik per Boolean einzuarbeiten.
Das Problem ist, dass diese Methoden zwar aufgerufen werden müssen. Sie werden aber in meiner Klasse nicht weiter implementiert. Die Methoden funktionieren leer! zB:

public void onNewAd(AdView arg0, int arg1, String arg2) {
// TODO Auto-generated method stub

}

Sobald sie aufgerufen wird, wird der Banner erzeugt. Unabhängig von ihrem Inhalt. Allerdings kann ich diese Methode auch nicht ausschalten. Sie wird automatisiert durchlaufen. Daher der Versuch sie in einer anderen Methode zu verschachteln.
 
Also jetzt versteh ich gar nichts mehr. Wenn die Methoden leer sind, warum dann überhaupt der Listener?!
 
Ich weiß nicht, ob Du schon mal mit AdBannern in Deinen Apps gearbeitet hast. Da kommt der Listener aus einer .jar. Die muss ich (grundsätzlich) so einbinden:

class Test extends Activity implements Listener

Dann muss ich aber die abstrakten Methoden übernehmen. Die sind leer. Werden aber dennoch durch:

adView.setAdViewListener(this);

angesprochen. Ohne den geht es nicht. Was intern tatsächlich abläuft kann ich nicht sagen. Ich wollte halt die abstrakten Methoden benutzen, um die Banner ein und auszublenden. Das geht auch. Das ganze sollte nun aber in der abstr. Methode eines anderen Banner-Anbieters laufen. Und da streikt eben der Listener.
 
Ok, nein sorry, dann kann ich dir nicht weiterhelfen. Das habe ich bisher noch nie ausprobiert und wäre jetzt nur Raten bei mir.

Trotzdem viel Erfolg noch.

Grüße
 

Ähnliche Themen

P
Antworten
6
Aufrufe
758
ppp
P
R
Antworten
29
Aufrufe
2.461
markus.tullius
markus.tullius
Temucin
Antworten
37
Aufrufe
2.566
markus.tullius
markus.tullius
Zurück
Oben Unten