在Android中,回调是什么?

87
我想了解回调函数的概念。我在网上搜索过关于回调函数的内容,看到很多使用接口的示例,其中一个类使用该接口调用另一个类的方法。但是我仍然无法理解回调函数的主要概念,使用回调函数的目的是什么?

链接:http://developer.android.com/guide/faq/commontasks.html#implementcallbacks - Vaibhav Jain
这是一种在Java中实现lambda表达式的方法,因为在Java 8之前不支持它们。 - Boris the Spider
6个回答

182

这里有一个不错的教程,其中很好地描述了回调和其使用场景。

回调的概念是,在另一个类中完成某些工作后,通知一个类同步/异步地。有些人称之为“好莱坞原则”:“不要叫我们,我们会叫你。”

这里有一个例子:

class A implements ICallback {
     MyObject o;
     B b = new B(this, someParameter);

     @Override
     public void callback(MyObject o){
           this.o = o;
     }
}

class B {
     ICallback ic;
     B(ICallback ic, someParameter){
         this.ic = ic;
     }

    new Thread(new Runnable(){
         public void run(){
             // some calculation
             ic.callback(myObject)
         }
    }).start(); 
}

interface ICallback{
    public void callback(MyObject o);
}

类A在线程中调用类B完成一些工作。如果线程完成工作,它将通过回调通知类A并提供结果。因此不需要轮询或其他操作。您将在结果可用时立即获得结果。

在Android中,回调在Activity和Fragment之间使用。由于Fragment应该具有模块化,因此可以在Fragment中定义回调来调用Activity中的方法。


3
非常感谢,现在我对回调有了一个概念。 - Hammad Shahid
1
非常感谢。这个例子真的非常简单和好。 - Mukesh Garg
抱歉打扰了,但我认为这个例子里有一个小错误。我认为“new Thread(new Runnable()...”的代码应该在B类的构造函数中。当我尝试运行你的示例时,我遇到了错误,但将代码放入构造函数后,它成功运行了。如果我有错,请见谅。 - Tim
在Android中,回调函数被用于例如在...之间的情况。 - nj2237
1
@nj2237的意思是“例如”。 - AD Progress
使用了太多简称,不过回答得很清楚明了。 - undefined

50

先创建一个接口,然后定义一个方法作为回调。在此示例中,我们将有两个类,一个是classA,另一个是classB

接口:

public interface OnCustomEventListener{
  public void onEvent();   //method, which can have parameters
}

在类B中的监听器本身(我们只在类B中设置了监听器)

private OnCustomEventListener mListener; //listener field

//setting the listener
public void setCustomEventListener(OnCustomEventListener eventListener) {
   this.mListener=eventListener;
}

在ClassA中,我们如何开始监听ClassB要传达的内容

classB.setCustomEventListener(new OnCustomEventListener(){
    public void onEvent(){
       //do whatever you want to do when the event is performed.
    }
});  

我们如何从 ClassB 触发一个事件(例如在按钮按下时)?

if(this.mListener!=null){
   this.mListener.onEvent();
}

附言:您的自定义监听器可以拥有任意数量的参数。

来源


这很有帮助 - 但我有一个问题...在上面的例子中,类B定义了监听器,这意味着任何想要监听事件的类都必须创建一个新的B对象,然后调用该方法。 例如 - 来自A类-> B b = new B(); b.setCustomEventListener(this);同样来自D类/ E类 B b = new B(); b.setCustomEventListener(this); 有没有办法可以避免在所有想要侦听的类中创建B对象? - akash89

10

回调在Java中非常有用。

使用回调,您可以通知另一个类异步操作已成功完成或出现错误。


4

回调接口在安卓中用于实现Fragment之间的通信。

请参考这里以获得更好的理解。


3

这里之前已经讨论过了(链接)

在计算机编程中,回调函数是一段可执行的代码片段,作为参数传递给其他代码,希望其他代码在某个方便的时候回调(执行)该参数。调用可以是立即进行的同步回调,也可以是稍后进行的异步回调。


2
我正在以下情况下使用: 在UI中,我从按钮中获取一个操作,例如用户想要下载500MB的文件。 然后,我会初始化后台引擎(AsyncTask类)并向其传递参数。 在UI上,我将显示阻止进度对话框并禁用用户进行任何其他点击。问题是:何时从UI中删除阻塞?答案是:当引擎成功或失败完成时,可以通过回调或通知实现。 什么是通知和回调之间的区别是另一个问题,但1:1比回调更快。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接