是什么——什么是回调
从调用方式上看,分为三种:同步调用,异步调用,回调。
根据理解,草草的画了个图
1. 同步调用:是一种阻塞式调用,如图1,程序执行到A,再执行到B,需要执行完B才会接着执行A,即在2–3–4执行的过程中不会执行5,整个流程应该是1–>A–>2–>B–>3–>4–>6
2. 异步调用:类似于消息和事件机制,解决同步阻塞问题。A执行到B后,A与B互不影响,不会等到B执行完A才执行。如图2,程序执行到A,然后分两条路:一条为A–>2–>B–>3–>4–>6,一条为A–>5–>6,虽然现在才去学习回调,其实早就在项目中已经使用过,曾经因为异步调用造成了空指针问题,原因是在第一条路线的过程中需要调用第二条路线的一个值,而这个时候第二条路线还没有执行完,也就还没有产生那个值,所以造成空指针。
3. 回调:双向式调用。即被调用者会持有调用者的一个引用,当执行完成通过引用通知调用者
为什么——回调的作用
一般用于层间协作(上层将本层的方法安转在下层,在下层满足条件时触发,图中A相当于上层,B相当于下层),用于分层的数据通讯。
怎么用 ——Java中实现接口回调
原理:
创建一个回调对象,再创建一个控制者对象,将回调对象要调用的方法告诉控制者对象,控制者对象负责检查某种情景或者某种条件是否满足,当满足的时候,自动触发回调方法。
这种说法很抽象
eg:
老板给员工指派一个任务,老板对员工说我把我的电话号码给你,当任务完成的时候,你就打电话告诉我。
例子中与原理一一对应为:
回调对象——老板
控制对象——员工
号码——回调的方法
打电话——回调的行为
老板把任务交给员工是持有员工的一个引用,当员工检查任务已经完成时,就告诉(回调)老板,而不需要老板自己去完成任务。
想象下这个场景,理解起来就容易多了。
代码演示
第一,定义一个回调接口
CallBack
package com.cd.callback;
/**
* 回调接口
* @author Sky
*
*/
public interface CallBack {
//需要回调的方法,即,当任务完成时要执行的方法
void task();
}
第二步,定义一个类实现这个接口
Boss
即,回调对象
package com.cd.callback;
/**
* 实现了回调接口的回调对象
* @author Sky
*
*/
public class Boss implements CallBack {
//回调执行的方法,当任务完成时调用
@Override
public void task() {
System.out.println("好的,我接收到了你的反饋,給你發獎金");
}
}
第三步,定义控制对象
Employee
package com.cd.callback;
/**
* 控制對象,持有回调对象的引用,在任务完成时,通知回调对象
* @author Sky
*
*/
public class Employee {
//定义一个变量
CallBack mCallBack;
//定义一个set方法传入回调接口,注入回调,也可以在构造方法中注入
// public Employee(CallBack callback){
// mCallBack=callback;
// }
public void setCallBack(CallBack callback){
mCallBack=callback;
}
public void doTask(){
//1,开始执行任务
for(int i=0;i<10;i++){
System.out.println("老板,第"+i+"件事做完了");
}
//2,告诉老板
mCallBack.task();
}
}
第四步,建一个测试类来测试代码
TestClass
package com.cd.callback;
public class TestClass {
public static void main(String[] args) {
//实例化控制器对象
Employee emp=new Employee();
//将回调对象传入,Boss实现了CallBack接口,直接传入Boss对象
emp.setCallBack(new Boss());
//控制对象执行任务
emp.doTask();
}
}
运行结果:
解释都写在注释里面。
Android中的接口回调
android中使用了大量的回调机制,比如activity的生命周期,activity在不同状态下回调的方法,还有最常见的Button点击事件
代码演示
众所周知,Button点击事件回调写法
package com.cd.callbackinandroid;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}
}
自定义回调:
package com.cd.callbackinandroid;
/**
*
* @author Sky
*自定义一个类
*/
public class CallbackClass {
/**
*
* 定义接口,即回调对象
*
*/
public interface OnclickListener{
void onclick();
}
/**
* 注入
* @param onclicklistener回调接口
*/
public void setOnClickListener(OnclickListener onclicklistener){
onclicklistener.onclick();
}
}
测试自定义回调
package com.cd.callbackinandroid;
import com.cd.callbackinandroid.CallbackClass.OnclickListener;
public class TestCallClass {
public static void main(String[] args) {
/**
* CallbackClass相当于Button
*/
CallbackClass c=new CallbackClass();
c.setOnClickListener(new OnclickListener() {
@Override
public void onclick() {
// TODO Auto-generated method stub
}
});
}
}
解释在注释里面。