Rückrufe sind in Wikipedia definiert wie:
Bei der Computerprogrammierung bezieht sich eine Rückruffunktion auf einen Verweis auf einen bestimmten ausführbaren Code, der über Funktionsparameter an einen anderen Code übergeben wird.
Ziel ist es, den zugrunde liegenden Code zuzulassen, dass Unterroutinen auf der höheren Ebene definiert werden.
Beispielsweise kann klarer sein: Die Verwendung von Nachrüstungen für Netzwerkanforderungen in Android als Beispiel ist ein Beispiel für asynchrone Rückrufe.
Nach der Einleitung einer Netzwerkanforderung kann die App andere Dinge fortsetzen. Das Ergebnis der Netzwerkanforderung wird im Allgemeinen durch die beiden Methoden von Onresponse und OnFailure erhalten. Schauen Sie sich den Code im relevanten Teil an:
call.enqueue (neuer Callback <HistoryBean> () {@Override public void onResponse (call <HistoryBean> call, Antwort <HistoryBean> Antwort) {HistoryBean hb = response.body (); if (hb == null) return; showText.append (hb.iserror () + "); for (historyBean (historyBean) (historyBean (historyBean (historyBean hb.getResults ()) {showText.Append (rb.gettitle () + "/n");Ignorieren Sie die Generika im obigen Rückruf. Nach der Definition in Wikipedia kann der gesamte Code in einer anonymen internen Klasse als Verweis auf einen bestimmten ausführbaren Code angesehen werden, der an andere Codes übergeben wird . Die beiden Methoden OnResponse und OnFailure sind Rückrufmethoden. Der zugrunde liegende Code ist der unveränderte Netzwerkanforderungsteil, der geschrieben wurde, und die durch die höhere Ebene definierte Unterprogramme ist der Rückruf. Da die spezifische Implementierung dem Benutzer übergeben wird, hat sie eine hohe Flexibilität. Das obige ist über die Methode Enqueue (Callback -Rückruf) verwandt.
Schritte der Rückrufmethode
Der oben erwähnte Rückruf ist ein sehr häufiges Konzept. Wenn Sie es auf das Programm schreiben, können Sie sagen:
In Klasse A wird eine Methode C in Klasse B aufgerufen und dann in Klasse B in der Klasse A in der Klasse A umgekehrt aufgerufen. D ist die Rückrufmethode. Klasse B ist der zugrunde liegende Code, und Klasse A ist der Code auf hoher Ebene.
Durch die obige Erklärung können wir also etwas schließen. Um die Universalität der Methode D darzustellen, verwenden wir das Schnittstellenformular, um die Methode D als Schnittstellenmethode zu erstellen. Wenn Klasse B die Methode D in Klasse A aufrufen möchte, muss die Klasse A diese Schnittstelle implementieren. Auf diese Weise wird es je nach Implementierung Polymorphismus geben, was die Methode flexibel macht.
Wenn Klasse A in Klasse B eine Methode C aufrufen will, muss die Klasse A einen Verweis auf B enthalten, andernfalls wird sie nicht aufgerufen. Dieser Schritt wird als Registrierungs -Callback -Schnittstelle bezeichnet. So implementieren Sie die Reverse Call -Methode D in Klasse A in der Klasse B direkt über die obige Methode C. Die Methode C in der Klasse B akzeptiert einen Schnittstellen -Typparameter. Nur in Methode C müssen Sie die Parameter dieses Schnittstellentyps verwenden, um die Methode D in der Klasse B aufzurufen, was wiederum Methode D in Klasse A aufnimmt. Dieser Schritt wird als Aufruf der Callback -Schnittstelle aufgerufen.
Dies implementiert auch, dass in der C -Methode der Klasse B die D -Methode in der Klasse A umgekehrt aufgerufen werden muss, was der Rückruf ist. A ruft B zum direkten Einstellen, der als Verwendung der zugrunde liegenden API für Code auf hohem Niveau angesehen werden kann. Wir schreiben oft solche Programme. B ruft A auf, um zurückzurufen, und für die zugrunde liegende API müssen Code auf hoher Ebene ausgeführt werden.
Lassen Sie uns schließlich die Schritte der Rückrufmethode zusammenfassen:
Callback -Beispiel
Nehmen wir einen Sohn, der Spiele spielt und darauf wartet, dass seine Mutter das Essen vorbereitet und seinen Sohn als Beispiel zum Essen und den oben genannten Schritten benachrichtigt, um einen Rückruf zu schreiben.
Im obigen Beispiel ist offensichtlich, dass der Sohn die Rückrufschnittstelle implementieren sollte und die Mutter die Callback -Schnittstelle aufrufen sollte. Deshalb definieren wir zuerst eine Callback -Schnittstelle und lassen unseren Sohn diese Callback -Schnittstelle implementieren.
Der Code ist wie folgt:
öffentliche Schnittstelle Callback {void eat ();} Der Sohn der öffentlichen Klasse implementiert Callback {Private Mom Mom; // Klasse A hält einen Verweis auf die Klasse B Public void setMom (mama mama) {this.mom = mama; } @Override public void eat () {System.out.println ("Ich bin hier, um eine Mahlzeit zu haben"); } public void Askmom () {// Aufrufen einer Methode mit Schnittstellenparametern durch eine Referenz auf Klasse B. System.out.println ("Wurde die Mahlzeit gekocht?"); System.out.println ("Nicht fertig, ich spiele das Spiel"); neuer Thread (() -> mama.docook (Sohn)). start (); System.out.println ("Spielen ..."); }}Dann müssen wir auch die Klasse einer Mutter definieren, die eine Methode mit Schnittstellenparametern enthält
öffentliche Klasse MOM {// Rufen Sie die Callback -Methode an, indem Schnittstellenparameter in einer Methode mit Schnittstellenparametern public void docook (Callback Callback) {neuer Thread (neu Runnable () {@Override public void Run () {try {system.out.Out.Println ("Cooking ..."); Thread.Sleep (5000); e.printstacktrace ();}}}). start (); }}Wir verabschieden eine Testklasse:
public class test {public static void main (String [] args) {mama mama = new mama (); Sohn Sohn = neuer Sohn (); Son.SetMom (Mama); Sohn.AskMOM (); }}Dieses Beispiel ist ein typisches Callback -Beispiel. Die Son -Klasse implementiert die Rückrufmethode der Schnittstelle. Es ruft Docook in der MOM -Klasse über die AskMOM -Methode auf, um die Callback -Schnittstelle zu registrieren. Dies entspricht dem Aufrufen von Code C der Klasse B in Klasse A. Docook in der Mutterklasse ruft die Eat in der Sohnklasse zurück, um die Ergebnisse in der Sohnklasse zu erzählen.
Auf diese Weise implementieren wir einen einfachen, definierten Rückruf.
Weitere Untersuchung von Callback -Beispielen
Schauen wir uns hauptsächlich den Code der Sohnklasse an:
Der Sohn der öffentlichen Klasse implementiert Rückruf {Public Mom Mom; öffentlicher Sohn (Mom Mama) {this.mom = mama; } public void Askmom () {System.out.println ("Wurde die Mahlzeit gekocht?"); System.out.println ("Ich habe es nicht gut gemacht, ich habe das Spiel gespielt"); neuer Thread (() -> mama.docook (Sohn)). start (); System.out.println ("Ich spiele das Spiel ..."); } @Override public void eat () {System.out.println ("Okay, ich bin hier, um eine Mahlzeit zu haben"); }}In dieser Klasse sind die wirklich nützlichen Teile neben der Ausgabe einiger Aussagen MOM.DOCOOK (Sohn) und die Umschreibung der EAT -Methode. Daher können wir diesen Rückruf durch die Form der anonymen inneren Klasse abkürzen. Der Code ist wie folgt:
public class callbacktest {public static void main (String [] args) {mama mama = new mama (); neuer Thread (() -> mama.docook (() -> System.out.println ("Ich habe eine Mahlzeit gehabt ...")). starten (); }}Die Sohnklasse abbrechen und die EAT -Methode direkt durch die anonyme innere Klasse in der Hauptmethode implementieren. In der Tat sind anonyme interne Klassen die Verkörperung von Rückrufen.
Asynchrone Rückrufe und synchrone Rückrufe
Rückruf: A Aufrufmethoden C in Klasse B und ruft dann Methode D in der Klasse A über die Klasse -A -Objekte in Methode C auf.
Lassen Sie uns über Asynchron und Synchronisation sprechen. Lassen Sie uns zuerst über das Konzept der Synchronisation sprechen.
synchron
Synchronisation bedeutet, dass beim Aufrufen einer Methode, wenn der vorherige Methodeaufruf nicht ausgeführt wird, nicht ein neuer Methodenaufruf getätigt werden kann. Mit anderen Worten, die Dinge müssen einzeln erledigt werden, und Sie können nur den nächsten nacheinander tun.
asynchron
Asynchronität ist relativ zur Synchronisation. Sie müssen nicht warten, bis der vorherige Methodenaufruf abgeschlossen ist, bevor Sie eine neue Methode aufrufen. Daher ist bei asynchronen Methodenaufrufen eine Methode erforderlich, um den Benutzer über das Methodenaufrufergebnis zu informieren.
Implementieren Sie asynchrone Methoden
Die häufigste Möglichkeit, Asynchron in Java zu implementieren, besteht darin, die Methode, die Sie asynchron in einem neuen Thread ausführen möchten, zu lassen.
Wir werden feststellen, dass eine Methode in einem asynchronen Methodenaufruf benötigt wird, um das Anrufergebnis des Benutzers zu informieren. Basierend auf dem oben genannten werden wir feststellen, dass die Rückrufmethode dafür geeignet ist, und den Benutzer über die Callback -Methode über das Anrufergebnis informieren.
Der asynchrone Rückruf erfolgt in einem neuen Thread, wenn eine Methode c von B. aufruft
Das obige Beispiel der Mutter, die ihren Sohn zum Abendessen benachrichtigt, ist ein Beispiel für einen asynchronen Rückruf. In einem neuen Thread wird die Docook -Methode aufgerufen und der Rückgabewert schließlich durch EAT akzeptiert. Natürlich ist die Essenz nach Verwendung der Lamdba -Optimierung gleich.
Synchroner Rückruf bedeutet, dass eine Methode b nicht in einem neuen Thread aufruft. Bei der Ausführung dieser Methode C können wir nichts tun und nur darauf warten, dass sie abgeschlossen ist.
Beispiele für synchrone Rückrufe und asynchrone Rückrufe
Schauen wir uns ein Beispiel eines synchronen Rückrufs in Android an:
button.setonclickListener (neue Ansicht.
Die Schaltfläche registriert die Rückruffunktion über setonclickListener und übergibt, wie oben beschrieben, die Referenz der Schnittstelle in Form einer anonymen internen Klasse. Da der Button SetonClickListener aufruft, ohne einen neuen Thread zu erstellen, ist dies ein synchroner Rückruf.
Asynchroner Rückruf ist das Beispiel, über das wir am Anfang gesprochen haben:
call.enqueue (neuer Callback <HistoryBean> () {@Override public void onResponse (call <HistoryBean> call, Antwort <HistoryBean> Antwort) {HistoryBean hb = response.body (); if (hb == null) return; showText.append (hb.iserror () + "); for (historyBean (historyBean) (historyBean (historyBean (historyBean hb.getResults ()) {showText.Append (rb.gettitle () + "/n");Diese Enqueue -Methode ist eine asynchrone Methode zum Anfordern von Remote -Netzwerkdaten. Wenn es intern implementiert wird, wird es über einen neuen Thread ausgeführt.
In diesen beiden Beispielen können wir feststellen, dass die Verwendung synchroner Rückrufe und asynchroner Rückrufe tatsächlich entsprechend den unterschiedlichen Anforderungen entworfen ist. Es kann nicht gesagt werden, dass einer den anderen ersetzt. In der Schaltfläche Klicken Sie beispielsweise oben, wenn es sich um einen asynchronen Rückruf handelt, wird der Klick -Effekt nicht sofort angezeigt, nachdem der Benutzer auf die Schaltfläche geklickt hat und der Benutzer keine anderen Operationen ausführt, sondern sich seltsam anfühlt. Asynchrone Rückrufe für Netzwerkanforderungen, da die angeforderte Ressource möglicherweise nicht vorhanden ist, die Netzwerkverbindung instabil ist, und aus anderen Gründen ist der Benutzer nicht klar über die Ausführung der Methode, sodass er asynchrone Rückrufe verwendet, den Methodenanruf initiiert und andere Dinge erledigt und dann auf die Rückrufbenachrichtigung warten kann.
Anwendung der Rückrufmethode in der Kommunikation
Die oben genannten Rückrufmethoden, mit Ausnahme der Rückrufe des Netzwerkanforderungs -Frameworks, haben alle keine Parameter. Schauen wir uns an, dass die Rückrufmethode Parameter hinzugefügt wird, um einige Kommunikationsprobleme zu implementieren.
Wenn wir möchten, dass die Klassen A nach einer Reihe von Berechnungen und Verarbeitung die Daten der Klasse B erhalten und die beiden Klassen nicht einfach auf Daten der Klasse A verweisen. Wir können Rückrufe in Betracht ziehen.
Die Schritte sind wie folgt:
Die oben genannten Schritte sind etwas abstrakt. Schauen wir uns ein Beispiel unten an, einer ist Client und der andere Server. Client fordert die zeitaufwändigen Daten des Servers an.
Public Class Client {öffentlicher Server; öffentliche String -Anfrage; // Linkserver und die Serverreferenz abrufen. öffentlicher Client Connect (Server Server) {this.server = server; gib dies zurück; } // Client, setzen Sie die Anfrage public client setRequest (String -Anforderung) {this.Request = request; gib dies zurück; } // Sende die Anforderungsmethode, Lamdba -Ausdruck. public void enqueue (server.callback callback) {neuer Thread (()-> Server.setCallback (Anfrage, Rückruf)). start (); }} öffentlicher Klassenserver {public String response = "Dies ist ein HTML"; // Registrieren Sie die Methode der Callback -Schnittstelle und geben Sie die Daten über Parameter Public void setCallback an die Callback -Schnittstelle weiter (String -Anforderung, Callback -Rückruf) {System.out.println ("Anforderung wurde empfangen und wird berechnet ..."); neuer Thread (() -> {try {thread.sleep (5000); callback.onResponse (Request + Antwort);} catch (interruptedException e) {e.printstacktrace (); callback.onfail (e);}}). start (); } // Schreiben Sie eine Schnittstelle in die Klasse, die den Daten der öffentlichen Schnittstelle besitzt. {Void onResponse (String -Antwort); void onfail (throwabbar); }}Schauen wir uns als nächstes das Testbeispiel an:
public class CallbackTest {public static void main (String [] args) {Client client = new Client (); client.connect (neuer Server ()). setRequest ("Was ist diese Datei?"). Enqueue (new server.callback () {@Override public void onResponse (String -Antwort) {System.out.Out.println (Antwort);} @Override öffentlich void onfail (throwable) {) {) {) {) {}}}}}}}}}}}}}}}}}}}}}}}}}). }}Die Ergebnisse sind wie folgt:
Die Anfrage wurde empfangen und wird berechnet ... Was ist diese Datei? Dies ist ein HTML
Das obige soll durch Rückrufe kommunizieren.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels für das Studium oder die Arbeit eines jeden hilfreich sein wird. Ich hoffe auch, Wulin.com mehr zu unterstützen!