Les rappels sont définis dans Wikipedia comme:
Dans la programmation informatique, une fonction de rappel fait référence à une référence à un certain code exécutable qui est transmis à un autre code via les paramètres de fonction.
Le but est de permettre au code sous-jacent d'appeler les sous-programmes définis au niveau supérieur.
Par exemple, il peut être plus clair: prendre l'utilisation de la rénovation pour les demandes de réseau dans Android comme exemple, il s'agit d'un exemple de rappels asynchrones.
Après avoir lancé une demande de réseau, l'application peut continuer d'autres choses. Le résultat de la demande de réseau est généralement obtenu via les deux méthodes d'onresponse et d'onfailure. Jetez un œil au code dans la partie pertinente:
call.enqueue (nouveau rappel <HistoryBean> () {@Override public void onResponse (call <HistoryBean> appel, réponse <HistoryBean> Response) {HistoryBean hb = réponse.body (); if (hb == null) return; showtex showText.APPEND (rb.getTitle () + "/ n");}} @Override public void onFailure (appel <HistoryBean>, Throwable T) {}});Ignorez les génériques dans le rappel ci-dessus. Selon la définition de Wikipedia, tout le code d'une classe interne anonyme peut être considéré comme une référence à un certain code exécutable transmis à d'autres codes . Les deux méthodes OnResponse et ONFAILURE sont des méthodes de rappel. Le code sous-jacent est la pièce de demande de réseau inchangée qui a été écrite, et le sous-programme défini par le niveau supérieur est le rappel. Étant donné que l'implémentation spécifique est remise à l'utilisateur, elle a une grande flexibilité. Ce qui précède est lié via la méthode ENQUEUe (rappel de rappel).
Étapes de la méthode de rappel
Le rappel mentionné ci-dessus est un concept très courant. Si vous le mettez sur l'écriture du programme, vous pouvez dire:
Dans la classe A, une méthode C dans la classe B est appelée, puis dans la classe B, la méthode D dans la classe A est appelée inverse. D est la méthode de rappel. La classe B est le code sous-jacent et la classe A est le code de haut niveau.
Ainsi, grâce à l'explication ci-dessus, nous pouvons déduire quelque chose. Afin de représenter l'universalité de la méthode D, nous utilisons le formulaire d'interface pour faire de la méthode appelée méthode d'interface. Si la classe B veut appeler la méthode D dans la classe A, la classe A doit implémenter cette interface. De cette façon, selon la mise en œuvre, il y aura du polymorphisme, ce qui rend la méthode flexible.
Si la classe A souhaite appeler une méthode C dans la classe B, la classe A doit contenir une référence à B, sinon elle ne sera pas appelée. Cette étape est appelée l'interface de rappel d'enregistrement. Alors, comment implémenter la méthode de l'appel inversé D dans la classe A dans la classe B, directement via la méthode ci-dessus C. La méthode C dans la classe B accepte un paramètre de type d'interface. Ensuite, uniquement dans la méthode C, vous devez utiliser les paramètres de ce type d'interface pour appeler la méthode D dans la classe B, qui à son tour appelle la méthode D dans la classe A. Cette étape est appelée appelant l'interface de rappel.
Cela implémente également que dans la méthode C de la classe B, la méthode D de la classe A doit être appelée à l'envers, qui est le rappel. A appelle B pour régler directement, qui peut être considéré comme utilisant l'API sous-jacent pour le code de haut niveau. Nous écrivons souvent des programmes comme celui-ci. B appelle A pour rappeler et l'API sous-jacente nécessite un code de haut niveau pour s'exécuter.
Enfin, résumons les étapes de la méthode de rappel:
Exemple de rappel
Prenons un fils en jouant à des jeux et en attendant que sa mère prépare le repas et informent son fils à venir manger à titre d'exemple, et suivons les étapes ci-dessus pour rédiger un rappel;
Dans l'exemple ci-dessus, il est évident que le fils doit implémenter l'interface de rappel et la mère doit appeler l'interface de rappel. Nous définissons donc d'abord une interface de rappel, puis laissons notre fils implémenter cette interface de rappel.
Le code est le suivant:
Rappel d'interface publique {void Eat ();} La classe publique son fils implémente le rappel {maman privée maman; // La classe A détient une référence à la classe B public void setmom (maman maman) {this.mom = maman; } @Override public void Eat () {System.out.println ("Je suis ici pour prendre un repas"); } public void askmom () {// appelant une méthode avec des paramètres d'interface via une référence à la classe B. System.out.println ("Le repas a-t-il été préparé?"); System.out.println ("Non fait, je joue au jeu"); Nouveau thread (() -> mom.docook (Son.Chis)). start (); System.out.println ("Playing the Game ..."); }}Ensuite, nous devons également définir une classe de mère, qui contient une méthode docook avec des paramètres d'interface
classe publique maman {// Appelez la méthode de rappel en utilisant les paramètres d'interface dans une méthode contenant des paramètres d'interface public void docook (rappel de rappel) {new thread (new Runnable () {@Override public void run () {try {system.out.println ("Cooking ..."); thread.sleep (5000); callback.eat ();} capture (interrupt. e.printStackTrace ();}}}). start (); }}Nous passons une classe de test:
Test de classe publique {public static void main (String [] args) {mom mom = new mom (); Fils fils = nouveau fils (); Son.setmom (maman); Son.askmom (); }}Cet exemple est un exemple de rappel typique. La classe de fils implémente la méthode de rappel de l'interface. Il appelle Docook dans la classe MOM via la méthode AskMom pour enregistrer l'interface de rappel, ce qui équivaut à appeler le code B de classe B dans la classe A. Docook dans la classe maman appelle les et venus de la classe Eat dans la classe de fils pour indiquer les résultats dans la classe de fils.
De cette façon, nous implémentons un rappel simple et défini.
Exploration plus approfondie des exemples de rappel
Examinons principalement le code de la classe de fils:
Le fils de classe publique met en œuvre un rappel {Maman publique maman; fils public (maman maman) {this.mom = maman; } public void askmom () {System.out.println ("Le repas a-t-il été préparé?"); System.out.println ("Je ne l'ai pas bien fait, j'ai joué au jeu"); Nouveau thread (() -> mom.docook (Son.Chis)). start (); System.out.println ("J'ai joué au jeu ..."); } @Override public void Eat () {System.out.println ("D'accord, je suis ici pour prendre un repas"); }}Dans cette classe, en plus de la sortie de certaines instructions, les parties vraiment utiles sont Mom.Docook (Son.Ce) et la réécriture de la méthode EAT. Par conséquent, nous pouvons abréger ce rappel par la forme d'une classe intérieure anonyme. Le code est le suivant:
classe publique CallBackTest {public static void main (String [] args) {mom mom = new mom (); nouveau thread (() -> mom.docook (() -> System.out.println ("J'ai eu un repas ...")). start (); }}Annulez la classe SON et implémentez directement la méthode EAT via une classe intérieure anonyme dans la méthode principale. En fait, les classes internes anonymes incarnent les rappels.
Rappels asynchrones et rappels synchrones
Rappel: une méthode d'appels C dans la classe B, puis appelle la méthode D dans la classe A à travers la classe A objets dans la méthode C.
Parlons d'asynchrones et de synchronisation, parlons d'abord du concept de synchronisation.
synchrone
La synchronisation signifie que lors de l'appel d'une méthode, si l'appel de méthode précédent n'est pas exécuté, un nouvel appel de méthode ne peut pas être passé. En d'autres termes, les choses doivent être faites une par une, et vous ne pouvez faire la suivante que les autres.
asynchrone
L'asynchrone est relative à la synchronisation, vous n'avez pas besoin d'attendre la fin de l'appel de méthode précédent avant d'appeler une nouvelle méthode. Par conséquent, dans les appels de méthode asynchrones, une méthode est nécessaire pour informer l'utilisateur du résultat de l'appel de la méthode.
Mettre en œuvre des méthodes asynchrones
La façon la plus courante d'implémenter Asynchronous en Java est de laisser la méthode que vous souhaitez exécuter de manière asynchrone dans un nouveau fil.
Nous constatons qu'une méthode est nécessaire dans un appel de méthode asynchrone pour informer le résultat de l'appel de l'utilisateur. Sur la base de ce qui précède, nous constatons que la méthode de rappel convient pour le faire et informer l'utilisateur du résultat de l'appel via la méthode de rappel.
Le rappel asynchrone se fait dans un nouveau fil lorsqu'une méthode d'appel C de B.
L'exemple ci-dessus de la mère avertissant son fils pour le dîner est un exemple de rappel asynchrone. Dans un nouveau fil, la méthode Docook est appelée et la valeur de retour est finalement acceptée par EAT. Bien sûr, après avoir utilisé l'optimisation LAMDBA, l'essence est la même.
Un rappel synchrone signifie qu'une méthode d'appels B n'est pas dans un nouveau thread. Lors de l'exécution de cette méthode C, nous ne pouvons rien faire et ne pouvons qu'attendre qu'il se termine.
Exemples de rappels synchrones et de rappels asynchrones
Regardons un exemple de rappel synchrone dans Android:
Button.setOnClickListener (new View.OnClickListener () {@Override public void onClick (View v) {log.i ("bouton", "cliquez sur");}});Le bouton enregistre la fonction de rappel via setOnClickListener et, comme écrit ci-dessus, transmet la référence de l'interface sous la forme d'une classe interne anonyme. Étant donné que le bouton appelle setOnClickListener sans créer un nouveau thread, il s'agit d'un rappel synchrone.
Le rappel asynchrone est l'exemple dont nous avons parlé au début:
call.enqueue (nouveau rappel <HistoryBean> () {@Override public void onResponse (call <HistoryBean> appel, réponse <HistoryBean> Response) {HistoryBean hb = réponse.body (); if (hb == null) return; showtex showText.APPEND (rb.getTitle () + "/ n");}} @Override public void onFailure (appel <HistoryBean>, Throwable T) {}});Cette méthode d'agitation est une méthode asynchrone pour demander des données de réseau distantes. Lorsqu'il est implémenté en interne, il est exécuté via un nouveau thread.
Grâce à ces deux exemples, nous pouvons voir que l'utilisation de rappels synchrones et de rappels asynchrones est en fait conçu en fonction des différents besoins. On ne peut pas dire que l'un remplace l'autre. Par exemple, dans l'événement de clic sur le bouton ci-dessus, s'il s'agit d'un rappel asynchrone, l'effet de clic n'apparaît pas immédiatement après que l'utilisateur clique sur le bouton et l'utilisateur n'effectuera pas d'autres opérations, il sera étrange. Des rappels asynchrones pour les demandes de réseau, parce que la ressource demandée peut ne pas exister, la connexion réseau est instable et d'autres raisons, l'utilisateur n'est pas clair sur l'exécution de la méthode, afin qu'ils utiliseront des rappels asynchrones, initier l'appel de la méthode et feront d'autres choses, puis attendent la notification de rappel.
Application de la méthode de rappel dans la communication
Les méthodes de rappel mentionnées ci-dessus, à l'exception des rappels du cadre de demande réseau, tous n'ont pas de paramètres. Jetons un coup d'œil à l'ajout de paramètres à la méthode de rappel pour mettre en œuvre certains problèmes de communication.
Si nous voulons que la classe A obtienne les données de la classe B après une série de calculs et de traitement, et les deux classes ne peuvent pas simplement se référer aux données de la classe A. Nous pouvons envisager des rappels.
Les étapes sont les suivantes:
Les étapes mentionnées ci-dessus sont un peu abstraites. Regardons un exemple ci-dessous, l'un est client et l'autre est le serveur. Le client demande les données longues du serveur.
Client de classe publique {serveur de serveur public; demande de chaîne publique; // Lien du serveur et obtenez la référence du serveur. Client public Connect (serveur Server) {this.server = server; retourner ceci; } // Client, Set Demande Client public setRequest (string request) {this.request = request; retourner ceci; } // Envoyez aussi de manière asquatique la méthode de demande, LAMDBA Expression. public void enqueue (server.callback callback) {new thread (() -> server.setCallback (request, rappel)). start (); }} public class Server {public String Response = "Ceci est un HTML"; // Enregistrez la méthode de l'interface de rappel et transmettez les données à l'interface de rappel via des paramètres public void setCallback (demande de chaîne, rappel de rappel) {System.out.println ("La demande a été reçue et est calculée ..."); nouveau thread (() -> {try {thread.sleep (5000); callback.onresponse (request + réponse);} catch (interruptedException e) {e.printStackTrace (); callback.onfail (e);}}). start (); } // Écrivez une interface dans la classe qui possède le rappel des données d'interface publique {void onResponse (String Response); vide onfail (jetable jetable); }}Ensuite, jetons un coup d'œil à l'exemple de test:
classe publique callbackTest {public static void main (string [] args) {client client = new client (); client.connect (nouveau serveur ()). setRequest ("Qu'est-ce que ce fichier?"). Enqueue (new server.callback () {@Override public void onResponse (réponse de la chaîne) {System.out.println (réponse);} @override public void onfail (landable lancent) {system.out.println (throwable.getMessage ();}); }}Les résultats sont les suivants:
La demande a été reçue et est calculée ... Quel est ce fichier? C'est un HTML
Ce qui précède est de communiquer à travers des rappels.
Ce qui précède est tout le contenu de cet article. J'espère que le contenu de cet article sera d'une aide à l'étude ou au travail de chacun. J'espère également soutenir plus Wulin.com!