Allgemeine Frage zur Syntax (Java) AsynchUtil.runAsynchronously(new Runnable() {})....

  • Hallo,


    ich habe kein praktisches Problem, ich muss nur für einen technischen Bericht die Thread-Erzeugung erklären.
    Mit dem nachfolgendenen Beispielcode wird ein Thread gestartet:


    public void Get() { // Capture property values in local variables before running // asynchronously.


    final CapturedProperties webProps = capturePropertyValues("Get");


    AsynchUtil.runAsynchronously(new Runnable() {


    @Override
    public void run() {
    try { performRequest(webProps, null, null); }
    catch (FileUtil.FileException e) { form.dispatchErrorOccurredEvent(Web.this, "Get", e.getErrorMessageNumber()); }
    catch (Exception e) { form.dispatchErrorOccurredEvent(Web.this, "Get", ErrorMessages.ERROR_WEB_UNABLE_TO_GET, webProps.urlString);
    }



    }
    }
    );
    }


    Meine Frage nun: Wie ist denn genau die folgende Zeile Java-syntax-mäßig (fachlich möglichst präzise und korrekt [Blockierte Grafik: https://www.androidpit.de/img/emoticons3/wink.png] ) zu erklären:
    AsynchUtil.runAsynchronously(new Runnable() {...})


    Also AsynchUtil ist eine Klasse aus dem Paket java.lang (richtig formuliert?)
    Mit dieser Zeile wird die statische Methode (da das Objekt AsynchUtil nicht erzeugt wurde, kann diese Methode ja nur aufgerufen werden, wenn sie statsich ist. richtig?) runAsynchronously aufgerufen. Diese Methode erhält als Paramter das frisch erzeugte Objekt (new) Runnable ohne Parameter ( () ). Soweit richtig? Und die geschweiften Klammern dahinter mit einem Programmcode drin... wie ist das java-mäßig genau zu erklären/rechtfertigen? Offensichtlich gehört das alles zum Übergabeparamter von runAsynchronously. Aber ich dachte immer, man kann nur Variablen (Datenfelder oder Objekte) als Parameter an eine Methode übergeben... und nicht ganze Programmcodes und schon garkeine geschweiften Klammern !?
    Ich bedanke mich schonmal.

  • also mal ganz abgesehen von dem Sinn des Codes, würde ich das so formulieren:


    • AsynchUtil ist eine Klasse (btw: diese kenne ich gar nicht) -> richtig
    • AsynchUtil.runAsynchronously ruft die statische Methode runAsynchronously der Klasse AsynchUtil auf -> richtig
    • genau. Die Methode erwartet einen Parameter von dem Typ Runnable. Runnable ist übrigens ein Interface.
    • Jetzt wird direkt an der Stelle des Parameters ein Objekt von einer sogenannte anonymen Klasse erzeugt und zwar "inline" - also direkt da wo der Parameter benutzt wird.

      • Du definierst also zuerst eine Klasse, die von dem Typ Runnable abgeleitet wird bzw. das Interface Runnable implementiert. Diese neue Klasse hat keinen Namen, ist also anonym.
      • Direkt an selber Stelle instanziierst du ein Object von dieser anonymen Klasse.
      • Du könntest das ganze auch einfach ganz traditionell über eine eigene richtige Klasse, also mit einer eigenen Datei, machen.
      • Der Vorteil bei dieser inline anonymen Klasse ist, dass du von ihr heraus auf alle Objekte des Eltern Objekts Zugriff hast.
      • Achtung, hier kann man schnell ein memory leak machen!

    Zugegeben, das war jetzt sehr schnell, aber ich hoffe ich konnte dir helfen. Ansonsten frage nochmal nach ;)

  • Danke, du hast das sehr gut erklärt :)


    Das mit dem Memory-Leak habe ich zwar nicht verstanden, weil ich mich mit sowas bisher noch nicht beschäftigt habe, aber den Rest habe ich fast ganz verstanden.


    Ich weiß, dass eine innere Klasse, egal ob anonym oder nicht, Zugriffe auf die Datenfelder der Äußeren Klasse Zugriff hat. Meinst du das mit "Zugriff auf alle Objekte des Elternobjekts"? Oder was wäre das Elternobjekt hier?

  • ja genau das meinte ich.


    Wegen den memory leaks, versuche ich mal ganz kurz dir das zu erklären.


    Alle Objekte die erzeugt werden, haben ja einen gewissen Speicherplatz im Memory. Dieser ist begrenzt. Immer wenn du das Keyword "new" benutzt wird also ein Speicher "reserviert".
    In manchen Programmiersprachen musst du dich darum kümmern, dass der Speicherplatz wieder freigegeben wird, sobald du das objekt nicht mehr brauchst (mit dem Keyword "delete" in C++).


    In Java passiert das automatisch auf eine gewisse magische Art. Und zwar macht das der sogenannte Garbage Collector (kurz GC).
    Sobald er Lust hat, löscht er also die Objekte im Speicher, wenn er denkt dass diese nicht mehr gebraucht werden.


    Wie weiss er welche Objekte noch gebraucht werden und welche nicht?
    Wenn es keine Referenzen mehr auf ein Objekt gibt, wird er es löschen.


    Jetzt gibt es (mittlerweile eher seltene) Fälle wo du in einer inneren Klasse Referenzen auf die äußere (Activity) Klasse hälst z.B. weil du eine View aus dem Layout referenzierst. Wenn du jetzt ein rotation change machst, wird ja das Layout neu aufgebaut. Der GC kann aber deine alte View nicht löschen und da hängt dann eine riesige Kaskade dahinter...


    Hier gibt es einen englischen Artikel über das Thema:
    http://android-developers.blog…voiding-memory-leaks.html


    Viele Grüße
    Jonas

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!