您的位置:首页 > 移动开发 > Android开发

siegen程的android技能树之回调函数(callback)

2016-04-16 15:33 363 查看
首先,什么是回调函数呢?

回调函数,维基百科上的定义是指通过函数参数传递到其它代码的,某一块可执行代码引用。这段定义看起来很容易让人犯迷糊。

举个例子来说,

有两个函数a,b和主函数c,

主函数c在运行过程中将b的引用传递给了a,这个动作就叫做在a中登记回调函数b。

然后主函数c继续运行,等到a运行(主函数调用或者事件触发)的时候,a调用登记在其中的b,这个动作叫做调用回调函数。

于是函数b开始运行。需要注意的一点是,因为b是由a调用的,所以函数b和函数a运行在同一个线程上。

关于回调函数,知乎上有一段比喻很是生动形象:

你到一个商店买东西,刚好你要的东西没有货,于是你(c)在店员(a)那里留下了你的电话(b),过了几天店里有货了,店员(a)就打了你的电话(b),然后你(c)接到电话后就到店里去取了货。在这个例子里,你的电话号码(b)就叫回调函数,你把电话留给店员(a)就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

(作者:常溪玲 链接:https://www.zhihu.com/question/19801131/answer/13005983)

现在我们知道了什么是回调函数,那么我们为什么要使用回调函数呢?

笔者大概总结了一下,使用回调函数的应用场景主要有三个。

场景1、函数a属于不可变的代码,它需要你给它提供实现方式函数b,所以这里就需要你将b的引用传递给a。

不可变代码大致有两种:

一是系统的库函数,编程分为两类:系统编程(system programming)和应用编程(application programming)。所谓系统编程,简单来说,就是编写;而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。系统程序员会给自己写的库留下一些接口,即API(application
programming interface,应用编程接口),以供应用程序员使用。所以在抽象层的图示里,库位于应用的底下。当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback
function)。

二是需要将内部细节隐藏起来的函数,只对外面露出接受函数引用的接口,从而增强代码的安全性。

场景2、函数b有很多种实现形式,通过选择在a中登记不同的b来达到动态绑定的效果,使程序更加灵活,降低耦合度。

场景3、用于异步回调的时候。

举个例子,主函数c在主线程中运行,它在a中注册回调函数b。然后启动子线程,并在子线程中运行a。运行的过程中a调用b,因为函数b是在主线程中注册的,所以b会包含主线程的数据,但是它现在却运行在子线程中。这样就完成了线程间通信,由于b中包含主线程的数据,所以大部分的操作都可以在子线程的b中完成,主函数c无需等待子线程的结束,这样就完成了异步调用。

回调函数的实现。

由于笔者学习的是java语言,所以具体来说说关于回调函数在java中的实现。相对于C语言来说,java的回调函数实现稍显麻烦一些,因为C语言中有函数指针,可以直接传递函数指针,java则是通过定义接口来实现回调函数。

具体的实现步骤如下。

class A实现接口InA
class A中包含一个class B的引用b
class B有一个参数为InA的方法test(InA a)
A的对象a调用B的方法传入自己,test(a)
然后b就可以在test方法中调用InA的方法

1、声明接口InA

public interface InA{
public void method();}

2、class A实现接口InA

<pre name="code" class="java">public class A implements InA
{
@override
public void method()
{
System.out.println("回调");
}

public static void main(String args[])
{
B b = new B();
b.set(new A());
b.call();
}
}




class B有一个参数为InA的方法set(InA a)

<span style="font-family: Arial, Helvetica, sans-serif;">public class B</span>
{
public InA a;

public void set(InA a)
{
this.a= a;
}

public void call(){
this.a.method();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: