2014-02-27 2 views
8

Ich habe für iOS und ich bin vertraut mit dem Konzept der Blöcke in Objective-C. Jetzt lehne ich Java für Android und versuche, einige Apps von Android auf iOS zu konvertieren.Abschlusshandler in Java?

Ich habe gelesen, dass es keine perfekte Entsprechung von Blöcken in Java gibt, also würde ich gerne wissen, welche die beste Alternative zur Implementierung von Completion-Handlern oder allem ist, was ähnlich funktionieren könnte.

Antwort

17

Interface-Typen, im Allgemeinen. Sie können Runnable (das ist ein interface) wie Rob vorgeschlagen, wenn Ihr Handler keine Parameter und eine void Rückgabetyp hat. Aber es ist einfach genug, Ihr zu definieren eigene:

interface CompletionHandler { 
    public void handle(String reason); 
} 

und es dann auf Ihre eigene Klasse zu übergeben:

something.setCompletionHandler(new CompletionHandler() { 
    @Override 
    public void handle(String reason) { 
     ... 
    } 
}); 

In der anderen Klasse:

void setCompletionHandler(CompletionHandler h) { 
    savedHandler = h; 
} 

und es dann einfach anrufen durch Aufruf der Methode:

savedHandler.handle("Some mysterious reason"); 

Diese Art von Sache wird für "Listeners" in Java Swing und Android-Bibliotheken überall gemacht; siehe zum Beispiel View.OnClickListener.

(P. S. Ich glaube, dass Java 8 lambdas mit all diesen Beispielen Schnittstelle nutzbar sein wird.)

+0

In der Tat werde ich einige Parameter benötigen. Ist es möglich, die 'CompletionHandler'-Schnittstelle nur einmal zu deklarieren und dann die' handle'-Methode zu überladen, wenn ich sie überschreibe? – Guilherme

+0

Sie würden * CompletionHandler' nur einmal deklarieren, und ja, Sie können dieselbe Syntax mehrmals mit anderem Code für 'handle' verwenden. Beachten Sie, dass Sie jedes Mal, wenn Sie dies tun, eine neue Klasse deklarieren, die CompletionHandler implementiert, aber eine anonyme Klasse ist. Wenn Sie den gleichen "handle" -Körper mehrere Male verwenden möchten, können Sie auch eine benannte Klasse deklarieren, die sie implementiert, und Sie können eine neue Instanz davon mit 'new' erstellen, z. 'setCompletionHandler (neuer CommonCompletionHandler());'. – ajb

3

Sie können Runnables ausführen. Offensichtlich wird das Äquivalent von Blöcken Lambdas erfordern, die in Java 8 kommen, aber wer weiß, wie lange sie noch von Android unterstützt werden (sie benutzen immer noch JUnit 3.8).

Es gibt viele Orte in Android, wo die Dinge getan werden, die wie Blöcke sind zum Beispiel:

this.currentConditionsActivity.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      currentConditionsActivity.onLocationChanged(...); 
     } 
    }); 
    instrumentation.waitForIdleSync(); 
    setupViewElements(); 

Wie Sie sehen können, müssen Sie eine Instanz einer anonymen Klasse machen, aber in den meisten IDEs, die Dummheit des Boilerplate wird durch Autofilling erleichtert. Dies wurde in Android Studio gemacht und es stellt das Ganze nach dem Ausführen von Runnable() wieder her (und wenn du den Code foldest, zeigt es sogar eine Syntax ähnlich der, die lambdas haben wird).

Also das ist der Zustand für jetzt. Nicht so schlimm, viele scheinen es ...

+0

Danke, das wie genau sieht, was ich brauchte. Noch eine kurze Frage, wie genau wird die Methode deklariert und wie rufe ich den Handler auf? – Guilherme

+0

Alle Runnables haben eine Methode ausgeführt, weshalb Android Studio sie einfach für Sie einspielen kann. Sie können auch Ihre eigenen anonymen Klassen definieren, einfach eine Schnittstelle deklarieren und dann einen neuen () {} erstellen und entweder die Methoden löschen oder Ihnen die Option zum Hinzufügen der Methoden geben. – Rob

+0

@Rob Wie hast du es am Ende gemacht? Alle einfachen Beispielcodes bitte – JayVDiyk