接口回调是指:
可以把使用实现了某一接口的类创建的对象的引用,赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。
以上一篇“ListView滑动到底部加载更多内容”为例:
1.下面是自定义ListView中的部分代码:
//声明接口变量
ILoadListener iLoadListener;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//当滚到最后一行且停止滚动时,显示布局,加载数据
if(isLastRow && scrollState == SCROLL_STATE_IDLE){
if(!isLoading){
isLoading = true;
footer.findViewById(R.id.load_layout).setVisibility(View.VISIBLE);
//接口回调(接口变量调用接口中的方法,而这个方法被接口的实现类,即此处的主Activity复写过了,所以相当于通知主Activity的对象调用接口中被自己复写过的方法)
iLoadListener.onLoad();
}
}
}
//相比而言,这就是自定义ListView一个普通函数了。
//如果你搞不明白这个函数的意义,你只要想一想,这个函数的作用是什么:“将传入的ILoadListener类型的对象,设置为自定义ListView中最上面声明的接口变量(调用onLoad方法的那个变量)”
public void setInterface(ILoadListener iLoadListener){
this.iLoadListener = iLoadListener;
}
//让主Activity去实现这个接口,然后复写接口中定义的空的onLoad方法。
//什么情况下用接口回调呢?听过一句话:“你(此处主Activity)想让别人(此处的自定义ListView)的代码执行你的代码,而别人的代码你又不能动”
//此处定义接口
public interface ILoadListener{
public void onLoad();
}
2.下面是主Activity中的部分代码(这个Activity实现了ILoadListener接口):
private void showListView(ArrayList<ApkEntity> apk_list) {
if (adapter == null) {
listView = (LoadListView) findViewById(R.id.id_listView);
//意思就是,我们的主activity对象(this),就是自定义ListView中最上面声明的接口变量,就是调用onLoad接口函数的那个对象
listView.setInterface(this);
adapter = new MyAdapter(this, apk_list);
listView.setAdapter(adapter);
}else{
adapter.onDateChange(apk_list);
}
}
//因为实现了接口,所以复写接口的方法
@Override
public void onLoad() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
getLoadData();
showListView(apk_list);
listView.loadComplete();
}
}, 2000);
}
指导思想:
面向对象设计的封装性,模块间要解耦,模块内要内聚
关键字:解耦
削弱模块间的协作性,也就是耦合性,使得模块之间高度独立,模块间更多的从事着单向的调用工作。一个模块需要某种服务就去找另一个模块,这使得程序呈现出层次性,高层通过接口调用底层,底层提供服务。摈弃模块间你中有我我中有你的暧昧关系。
关键字:协作
但我们又需要模块间的协作,所以需要回调(C++中是指针)。如果A对象关心B对象的状态变化,那么给B对象的状态的变化注册接口回调函数,A实现接口,让接口函数通知A,B对象状态的改变,这样在封装了模块变化的同时实现了模块间的协作关系,另辟独径的给对象解耦。
关键字:变量
回调函数跟普通函数只是在调用函数时略有区别。一般调用普通函数时,直接写函数名即可。但是在调用所谓“回调”函数时,是把它作为参数传递给另一函数。关键就在于“参数”这两个字。为什么要把某个东西参数化?就是它存在变化的可能性。既然可以把变量做成参数,那么函数也同样可以做成参数,只要它们有变化的可能。对于一成不变的东西,显然直接嵌入便可。