Detailed explanation of Java callback methods
Callback is defined in Wikipedia as:
In computer programming, a callback function refers to a reference to a certain block of executable code that is passed to other code through function parameters.
The purpose is to allow low-level code to call subroutines defined at higher levels.
An example may make it clearer: take the use of retrofit to make network requests in Android as an example. This is an example of asynchronous callback.
After initiating a network request, the app can continue with other things. The results of the network request are generally returned through the onResponse and onFailure methods. Take a look at the relevant part of the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Ignore the generics in CallBack above. According to the definition in Wikipedia, all the code in the anonymous inner class can be regarded as function parameters passed to other codes. A certain block can A reference to the executing code. The two methods onResponse and onFailure are callback methods. The underlying code is the unchanged network request part that has been written, and the subroutine defined by the higher level is the callback. Because the specific implementation is left to the user, it has a high degree of flexibility. The above is related through the enqueue(Callback callback) method.
Steps of the callback method
The callback mentioned above is a very general concept. When it is put into program writing, it can be said:
Class A calls the method in class B A certain method C, and then class B in turn calls method D in class A, where D is the callback method. Class B is the low-level code, and Class A is the high-level code.
So through the above explanation, we can infer something. In order to express the versatility of the D method, we use the form of an interface to call the D method an interface method. Then if class B wants to call class A Method D, then class A must implement this interface. In this way, depending on the implementation, there will be polymorphism, making the method flexible.
If class A wants to call a method C in class B, class A must contain a reference to B, otherwise it cannot be called. This step is called registering the callback interface. So how do you implement class B to in turn call method D in class A? Directly through the above method C. Method C in class B accepts a parameter of an interface type, so you only need to use this interface type in method C. To call method D with the parameters, you can in turn call method D in class A in class B. This step is called calling the callback interface.
This also realizes that the C method in class B needs to call the D method in class A in turn. This is the callback. A calling B is a direct call, which can be seen as high-level code using the underlying API. We often write programs this way. B calling A is a callback, and the underlying API requires high-level code to execute.
Finally, to summarize, the steps of the callback method:
Class A implements the interface CallBack callback
Class A contains a reference to B
B There is a method f(CallBack callback) with a parameter of CallBack
Call the method f(CallBack callback) of B in class A - register the callback interface
B can call it in f(CallBack The method of calling A in the callback) method - calling the callback interface
Example of callback
Let's take a son playing a game and waiting for his mother to prepare the meal and then notify the son to eat it. Follow the above steps to write the callback;
In the above example, it is obvious that the son should implement the callback interface, and the mother should call the callback interface. So we first define a callback interface, and then let our son implement this callback interface.
The code is as follows:
1 2 3 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Then we also need to define a mother class, which has a method doCook with interface parameters
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
We pass a test class:
1 2 3 4 5 6 7 8 |
|
This example is a typical callback example. The Son class implements the callback method of the interface. It calls doCook in the Mom class through the askMom method to implement the registration callback interface, which is equivalent to the code C in class A that calls class B. The doCook in the Mom class calls back the eat in the Son class to tell the Son class the result.
In this way, we have implemented a simple callback that meets the definition.
Further exploration of callback examples
We mainly look at the code of the Son class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
In this class, except In addition to outputting some statements, the really useful parts are mom.doCook(Son.this) and overriding the eat method. Therefore, we can abbreviate this callback in the form of an anonymous inner class. The code is as follows:
1 2 3 4 5 6 |
|
Cancel the Son class and implement the eat method directly through the anonymous inner class in the main method. In fact, anonymous inner classes are the embodiment of callbacks.
Asynchronous callback and synchronous callback
Callback As we said above, A calls method C in class B, and then calls method D in class A through the object of class A in method C. .
We are talking about asynchronous and synchronic, let’s talk about the concept of synchronization first
Synchronization
Synchronization refers to when calling a method, if the previous method call has not been completed , it is impossible to make new method calls. That is to say, things must be done one by one. After finishing the previous one, you can do the next one.
Asynchronous
Compared with synchronization, asynchronous does not need to wait for the previous method call to end before calling a new method. Therefore, in an asynchronous method call, a method is needed to notify the user of the result of the method call.
How to achieve asynchronous implementation
在Java中最常实现的异步方式就是让你想异步的方法在一个新线程中执行。
我们会发现一点,异步方法调用中需要一个方法来通知使用者调用结果,结合上面所讲,我们会发现回调方法就适合做这个事情,通过回调方法来通知使用者调用的结果。
那异步回调就是A调用B的方法C时是在一个新线程当中去做的。
上面的母亲通知儿子吃饭的例子,就是一个异步回调的例子。在一个新线程中,调用doCook方法,最后通过eat来接受返回值,当然使用lamdba优化之后的,本质是一样的。
同步回调就是A调用B的方法C没有在一个新线程,在执行这个方法C的时候,我们什么都不能做,只能等待他执行完成。
同步回调与异步回调的例子
我们看一个Android中的一个同步回调的例子:
1 2 3 4 5 6 |
|
button通过setOnClickListener注册回调函数,和上面写的一样,通过匿名内部类的形式将接口的引用传进去。由于button调用setOnClickListener没有新建一个线程,所以这个是同步的回调。
而异步回调,就是我们开篇讲的那个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
这个enqueue方法是一个异步方法去请求远程的网络数据。其内部实现的时候是通过一个新线程去执行的。
通过这两个例子,我们可以看出同步回调与异步回调的使用其实是根据不同的需求而设计。不能说一种取代另一种,像上面的按钮点击事件中,如果是异步回调,用户点击按钮之后其点击效果不是马上出现,而用户又不会执行其他操作,那么会感觉很奇怪。而像网络请求的异步回调,因为受限于请求资源可能不存在,网络连接不稳定等等原因导致用户不清楚方法执行的时候,所以会用异步回调,发起方法调用之后去做其他事情,然后等回调的通知。
回调方法在通信中的应用
上面提到的回调方法,除了网络请求框架的回调除外,其回调方法都是没有参数,下面,我们看一下在回调方法中加入参数来实现一些通信问题。
如果我们想要A类得到B类经过一系列计算,处理后数据,而且两个类是不能通过简单的将B的引用给A类就可以得到数据的。我们可以考虑回调。
步骤如下:
在拥有数据的那个类里面写一个回调的接口。-->这里就是B类中写一个回调接口
回调方法接收一个参数,这个参数就是要得到的数据
同样是在这个类里写一个注册回调的方法。
在注册回调方法,用接口的引用去调用回调接口,把B类的数据当做参数传入回调的方法中。
在A类中,用B类的引用去注册回调接口,把B类中的数据通过回调传到A类中。
上面说的步骤,有点抽象。下面我们看一个例子,一个是Client,一个是Server。Client去请求Server经过耗时处理后的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
接下来,我们看一下测试的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
结果如下:
1 2 |
|
以上就是通过回调的方式进行通信。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持PHP中文网!
更多Java回调方法详解相关文章请关注PHP中文网!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Discussing the hierarchical architecture problem in back-end development. In back-end development, common hierarchical architectures include controller, service and dao...

How to use OAuth2.0's access_token to achieve control of interface access permissions? In the application of OAuth2.0, how to ensure that the...

Discussing the hierarchical architecture in back-end development. In back-end development, hierarchical architecture is a common design pattern, usually including controller, service and dao three layers...

Questions and Answers about constant acquisition in Java Remote Debugging When using Java for remote debugging, many developers may encounter some difficult phenomena. It...

How to convert names to numbers to implement sorting within groups? When sorting users in groups, it is often necessary to convert the user's name into numbers so that it can be different...

Confused with choosing Java project management tools for beginners. For those who are just beginning to learn backend development, choosing the right project management tools is crucial...

Exploring the application of ultimate consistency in distributed systems Distributed transaction processing has always been a problem in distributed system architecture. To solve the problem...

Analysis of the reason why Python script cannot be found when submitting a PyFlink job on YARN When you try to submit a PyFlink job through YARN, you may encounter...
