什么是回调?##
先举个通俗易懂的例子
经理要出差,给某个员工安排了任务(挖了个坑就不管了,员工你去填坑。这个坑就是回调),临走前吩咐,任务做完了记得通知我.
定义回调规范CallBack
/**
* 约定一个消息(经理留下手机号码),员工做好了,打电话给经理。经理才知道
* @author afei
*
*/
public interface CallBack {
/**
*
* @param feedback 员工做好后,得通知经理
*/
void callback(String feedback);
}
Manager
/**
* 实现回调规范(我跟员工的约定,他做好了打电话通知我)
* 我这里实现callback就是把手机带上。要不然员工上哪儿通知我。
* @author afei
*
*/
public class Manager implements CallBack {
/**
* 经理接到员工的电话,收到消息
*/
@Override
public void callback(String feedback) {
System.out.println("给我的反馈信息是:" + feedback);
}
}
定义一个调用类
public class Afei {
/**
*
* @param callback 就是做好了,我得通知经理啊(比如给打打电话,发邮件etc...
* 临走前,经理留下了电话号码。我做好了,就骚扰他)
*/
void doTask(CallBack callback) {
String msg = "我做好了";
callback.callback(msg);
}
}
测试
public class Client {
public static void main(String[] args) {
//员工做经理给的任务
new Afei().doTask(new Manager());
}
}
输出
给我的反馈信息是:我做好了
不知各位看官理解没有,没有的话,再来一个Android开发的例子。基本模拟activity调用过程,当然,实际情况复杂多了。。。
/**
* 定义回调
* @author afei
*
*/
public abstract class Activity {
abstract void onCreate(Map<String, String> bundle);
}
/**
* 定义回调调用者
* @author afei
*
*/
public class OS {
static Map<String, String> bundle;
static {
bundle = new HashMap<String, String>();
}
void performCreate(Activity activity) {
bundle.put("createdMsg", "the bundle be created by OS");
activity.onCreate(bundle);
}
}
/**
* 模拟系统调用入口
* @author afei
*
*/
public class Client {
public static void main(String[] args) {
new OS().performCreate(new OneActivity());
}
}
Android开发者
/**
* 使用回调,开发人员填充代码
* @author afei
*
*/
public class OneActivity extends Activity {
@Override
void onCreate(Map<String, String> savedInstanceState) {
System.out.println("实例化布局,并且使用系统实例化的变量:" + savedInstanceState);
}
}
运行Client.main()方法,输出
实例化布局,并且使用系统实例化的变量:{createdMsg=the bundle be created by OS}
看到这里的同鞋maybe会问道,你怎么知道activity是怎么调用的?
下面我们来测试一下Android系统activity调用过程
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
throw new Exception("MY_EXCEPTION");
} catch (Exception e) {
e.printStackTrace();//使用该方法,可以清晰的知道方法之间的调用关系
}
}
}
activity-call.png
preformCreate.png
callActivityOnCreate.png
ActivityThread.main.png
来自知乎https://www.zhihu.com/question/20284432
Android应用程序的入口点是什么?ActivityThread?onCreate?
是一个搞 Android 开发的朋友,面试的时候被问一个"Android应用程序的入口点是什么?"
他回答ActivityThread,结果面试的人一脸茫然;他再说onCreate,面试官就”说这就对了嘛”
summary##
现在再来总结回调,Java代码的回调函数经常由框架或是系统定义,由程序开发人员填充。回调函数包含:
调用者:如dbutils中的QueryRunner。
回调规范:即一个接口,如dbutils中的ResultSetHandler<T>。其中可以定义N多个它的子类。
返回的数据:由用户自己定义,或是系统已经定义。
/**
* 定义回调规范
*/
public interface Protocol<T> {
/**
* @param val 留着回调使用
* @return
*/
public T obj(int val);
}
/**
* 定义调用者
*/
public class Runner {
/**
*
* @param customNum 自定义数字
* @param protocol 用户实现的接口
* @param <T> 定义泛型
* @return
*/
public <T> List<T> getObjs(int customNum,Protocol<T> protocol){
List<T>list = new ArrayList<T>();
for (int i = 0;i< customNum;i++){
T ret = protocol.obj(i);
list.add(ret);
}
return list;
}
}
public class Client {
public static void main(String[] args) {
Runner runner = new Runner();
// List<String> objs = runner.getObjs(20, new Protocol<String>() {
// @Override
// public String obj(int val) {
// return "hello" + val;
// }
// });
List<String> num = runner.getObjs(30,(val)->{return "hello"+val;});//lambda
System.err.println(num);
}
}
运行Client.main()输出结果
[hello0, hello1, hello2, hello3, hello4, hello5, hello6, hello7, hello8, hello9, hello10, hello11, hello12, hello13, hello14, hello15, hello16, hello17, hello18, hello19, hello20, hello21, hello22, hello23, hello24, hello25, hello26, hello27, hello28, hello29]
网友评论