在编写Android程序的时候,我们经常会写到类似这样的程序:
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//do something
}
});
当指定的button被按下时便会触发onClick()方法,这个便是Android中被广泛使用的回调。回调可以简单地这样理解:Class A调用了Class B的方法C,在方法C中Class B又回过头调用了Class A的方法D,这一过程便被称为回调,方法D被称为Class A的回调函数。
那么如何定义一个回调呢?这其实是有一定套路的,如下:
(1)定义接口:在类中定义一个Interface,并在接口中定义一个抽象方法;
(2)接口对象:在类中定义一个该接口的成员变量;
(3)设置对象:在类中定义一个公共的方法,可以设置这个接口的对象,调用该方法给接口对象成员变量赋值;
(4)调用方法:在合适的位置调用接口对象中的方法。
以上套路来源于网络,不过看上去还是有些抽象,下面将用代码直观地解释一下:
public interface Callback {//第一步:定义接口
public void onClick();
}
public class Button {
private Callback listener;//第二步:接口对象
public void click() {
listener.onClick();//第四步:调用方法
}
/***第三步:设置对象***/
public void setOnclickListener(Callback listener) {
System.out.println("Button:注册监听(其实就是将Button与实际回调函数绑定)");
this.listener = listener;
}
public static void main(String[] args) {
Button btn = new Button();
btn.setOnclickListener(new Callback(){//调用Button的setOnclickListener方法
@Override
public void onClick() {
System.out.println("onClick:回调");
}
});
btn.click();//Button调用了Callback的onClick方法,这里即为回调
}
}
代码具体地对应哪一个步骤注释中已经给出,其实稍作整理之后会发现实际上Android的回调机制并不难以理解。不过有的人估计还是会疑惑(比如我- -):回调机制的本质不就只是A调用B,然后B再回过头调用A而已吗,为什么要抽象出一个接口来呢?比方说下面的代码:
public class Employee {
public void work(Boss boss){
System.out.println("Boss叫我工作。。。");
String result = "工作完成了!";
boss.result(result);//Employee调用Boss的result方法,回调
}
}
public class Boss {
public Boss(Employee employee) {
employee.work(this);//Boss调用Employee的work方法
}
public void result(String result) {
System.out.println(result);
}
public static void main(String[] args) {
Employee employee = new Employee();
Boss boss = new Boss(employee);
}
}
上面的代码通过不使用接口的方法来实现回调功能,显然这样也是可以的。但是我们要考虑到一个情况,你的Boss可能有多位,如果是按照上面代码的逻辑,那么你就需要在Employee中重载多个work方法,这样就让代码显得臃肿了,而通过抽象出一个接口,让不同的Boss类根据各自需要分别实现该接口,而作为下属的Employee则只要通过一个接口便可以和多个Boss汇报情况,还是比较抽象?请看下面代码:
public interface Callback {
public void result(String result);
}
public class Employee {
public void work(Callback callback) {
System.out.println("Boss叫我工作。。。");
String result = "报告"+callback.toString()+"工作完成了!";
callback.result(result);//Employee调用callback的result方法,回调
}
}
public class Boss implements Callback{
public Boss(Employee employee) {
employee.work(this);//Boss调用Employee的work方法
}
@Override
public void result(String result) {
System.out.println(result);
}
public static void main(String[] args) {
Employee employee = new Employee();
Boss boss = new Boss(employee);
}
}
由于回调在Android中如此的普遍,所以充分理解回调机制将有助于我们对Android编程的理解。