虽然知道Android中组件的“监听”的方式采用一种回调的方式,但是对于回调的具体体现实行却不得而知。今天就针对回调这个方法做一个比较详细的笔记。
回调:不是该函数的实现方直接调用,而是在特定的事件或条件发生时有另外一方来调用,对该事件或条件进行事件的响应。
举一个最简答的回调的例子:
- 创建一个接口,这是一个回调接口
public interface Callback {
void postExec();
}
- 创建一个方法,进行回调操作。call.postExec();
public class A {
private Callback call;
public void setCallBack(Callback callBack){
this.call=callBack;
}
public void doSth(){
System.out.println("AAAAAAAAAAA");
call.postExec();
}
}
- 实现接口,并进行回调: a.doSth();
package com.callback.one;
public class B {
public static void main(String[] args){
A a= new A();
a.setCallBack(new Callback() {
@Override
public void postExec() {
// TODO Auto-generated method stub
System.out.println("CallBack is run");
}
});
a.doSth();
}
}
上面是一个简单的例子,通过一个接口和两个类文件来进行回调。如果是本身进行回调呢?
public class CallBackTest1 {
public void show(ICallback callback){
Long beginTime=System.currentTimeMillis();
callback.excuteStr(); // 进行回调
long endTime=System.currentTimeMillis();
System.out.println("Time is "+ (endTime - beginTime));
}
public static void main(String[] str){
CallBackTest1 callBackTest=new CallBackTest1();
callBackTest.show(new ICallback() {//执行回调函数
@Override
public void excuteStr() {
// TODO Auto-generated method stub
System.out.println("ok, this is callback! ");
}
});
}
public interface ICallback {
void excuteStr();
}
}
再来重温一下回调函数的定义:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,这种机制就称为回调。
根据已经给出的例子,我们利用定义来分析一下:第一个例子,类A类中定义了方法public void doSth(),来调用接口中的抽象方法call.postExec();类B中调用了类A的public void doSth()方法,同时实现了抽象方法public void postExec()。即类调用了一个由其他类(或本身)实现的接口的方法。
所以实现回调函数的步骤是:
- 创建一个回调接口,其有数个回调方法。
- 通过方法a调用接口的函数(回调函数)
- 方法b来调用方法a,实现接口函数。
即对于回调函数,可以找到其调用接口函数的方法,然后再进行追溯。
在Android中,很多内容都涉及到了回调函数。比如Android基础知识中,Button组件的监听事件。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn= (Button)this.findViewById(R.id.btn);
final TextView tv= (TextView) this.findViewById(R.id.tv);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv.setText("the Button is click");
}
});
}
这是一个简单的Button的点击事件,这里btn.setOnClickListener(new View.OnClickListener()作为一个回调方法。可以在View.java文件中获知:
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
通过层层搜索,最后发现,该方法间接地调用了接口的onClick()方法。