1、回调函数的定义
回调函数是通过一个函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这叫回调函数。由于java中没有指针,我们通常通过interface来实现回调。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件下由另一方调用,用于对该事件或者条件进行响应。
2、回调通俗点的理解
假设有两个类,分别是甲类和乙类,甲类调用乙类的方法,然而乙类并不能独自完成,它需要甲类中某个函数的帮助,就调用该函数,这个函数是在甲类中实现的,但是甲类自己没有用,确切的说没有直接调用,而是通过乙类来间接的调用了,毕竟是甲类想做这件事的,来找乙类来帮忙的。乙类中调用甲类中的那个函数就叫回调函数。
3、一个例子让你发现,原来回调我们一直都在使用
在Android学习过程中,我们会经常使用为某个控件比如Button、TextView或者ImageView添加监听事件,Button最濒繁使用的是添加点击事件,通过setOnClickListener()来注册监听,然后我们通过匿名内部类或者实现OnClickListener接口来重写OnClick()方法。相信这个过程大家都熟悉,其实秘密就在为控件注册监听这个方法中,我们来看看源码是如何实现的:
/**
* Register a callback to be invoked when this view is clicked. If this view is not
* clickable, it becomes clickable.
*
* @param l The callback that will run
*
* @see #setClickable(boolean)
*/
public void setOnClickListener(OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
好多人一看源码头就疼,其实我也一样,但是没办法,不看就不能透彻的理解我们学的知识,慢慢来吧!先看上面的注释,大体意思是:当该控件被点击时,注册一个回调函数给她调用。如果该控件之前是不可点击的,则将它变为可点击的。大家注意该函数的参数了吗?这个参数是一个接口类型的。
/**
* Call this view's OnClickListener, if it is defined. Performs all normal
* actions associated with clicking: reporting accessibility event, playing
* a sound, etc.
*
* @return True there was an assigned OnClickListener that was called, false
* otherwise is returned.
*/
public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
return true;
}
return false;
}
这也是在View源码中,上面注释的意思是:如果控件被注册了,则调用该控件的监听方法,执行的所有动作都与点击有关,比如报告可访问性的活动、播放声音等等。其中关键代码即使红色标记的部分。
在MainActivity中我们通过private Button button;来声明一个Button,持有对Button的引用。这个MainAcitvity类等价以上面的甲类,而Button类相当于乙类,甲类找乙类帮忙首先需要持有乙类的电话号码(引用),然后乙类找它的小弟setOnClickListener()来做这件事,但是这个小弟需要甲类中的一个叫CallBack(在本例中指OnClickListener)的朋友来帮忙,而这个CallBack则通过它的方法(该方法在MainActivity中实现就是OnClick,其中MainActivity实现了CallBack接口)调用来帮忙,红色字体的代码就是这个CallBack朋友帮忙的过程。可能关系有点乱,多看两遍就理解了。
可能有人会问上面的 getListenerInfo()是个什么鬼?其实它是个监听信息对象,它里面包含了众多的监听接口包括OnLongClickListener、OnKeyListener、OnTouchListener等等。
4、使用回调的步骤
(1) 定义一个接口CallBack,让A类实现该接口。
(2) A类中持有一个B类的引用小b。
(3) B类中有一个参数类型为CallBack的函数public void Method(CallBack callBack)。
(4) A类的对象小a通过获得引用小b调用方法Method。
(5) 在Method方法中通callBack调用在A类中实现的接口方法。
5、为什么要用回调呢?用它能带来什么好处?
这里我感觉这篇博客讲的很好 http://hellosure.iteye.com/blog/1130176