很早以前不知道如何解释清楚回调函数(CallBack),在知乎上看到一个回答特别形象,当时就收藏了,因此今天决定用代码的形式再让这个回答更加深入点。ide
而后再看看 Android 里的应用。this
什么是回调函数设计
Android 里常见的回调code
维基的解释:对象
在计算机程序设计中,回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指经过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计容许了底层代码调用在高层定义的子程序。接口
我认为通俗易懂的解释:事件
你到一个商店买东西,恰好你要的东西没有货,因而你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,而后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫作触发了回调关联的事件,店员给你打电话叫作调用回调函数,你到店里去取货叫作响应回调事件。回答完毕。get
可能看着通俗的解释可以知道是怎么回事,可是轮到本身要去实现一个回调的时候,就有点步履维艰了。因此我简单将那个解释,转换成了代码再解释一番。回调函数
首先我得定义一个接口(个人电话号码):
public interface INumber { public void onCall(); }
我去商店买东西,该商店对象刚刚初始化:
Store store = new Store();
而后我才得知商店刚刚开门没有我要的货(商店构造函数):
public class Store { public Store() { Utils.sout("才开店,没有货"); Utils.sout("============="); } }
因此我把个人电话号码留给店员,对于店员来讲就是获得个人电话号码(注册事件):
private INumber number; public void setNumber(INumber number) { this.number = number; } public void call() { number.onCall(); } /**************注册前的准备工做完毕**************/ public static void main(String[] args) { Store store = new Store(); // 先注册好事件 store.setNumber(new INumber() { @Override public void onCall() { Utils.sout("============="); Utils.sout("货到了"); } }); for (int i = 1; i < 4; i++) { Utils.sout("模拟取货:" + i + "小时"); } // 货到了就打电话通知我 store.call(); }
总体控制台输出:
才开店,没有货
= = = = = = = = = = = = =
模拟取货:1小时
模拟取货:2小时
模拟取货:3小时
= = = = = = = = = = = = =
货到了
-
商店类的完整代码:
public class Store { public Store() { Utils.sout("才开店,没有货"); Utils.sout("============="); } private INumber number; public void setNumber(INumber number) { this.number = number; } public void call() { number.onCall(); } public static void main(String[] args) { Store store = new Store(); store.setNumber(new INumber() { @Override public void onCall() { Utils.sout("============="); Utils.sout("货到了"); } }); for (int i = 1; i < 4; i++) { Utils.sout("模拟取货:" + i + "小时"); } store.call(); } }
咱们常常这样写:
btShowDialog = (Button) findViewById(R.id.bt_showdialog); btShowDialog.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // do something } });
咱们常常能够看到这样相似的代码,监听一个按钮的点击事件,当用户点击以后,咱们执行一些逻辑。
这里的 setOnClickListener()
就跟咱们以前店员得到个人电话号码的方法同样 setNumber()
注册好事件。
源码:
/** * 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(@Nullable OnClickListener l) { if (!isClickable()) { setClickable(true); } getListenerInfo().mOnClickListener = l; } /** * Interface definition for a callback to be invoked when a view is clicked. */ public interface OnClickListener { /** * Called when a view has been clicked. * * @param v The view that was clicked. */ void onClick(View v); }
到这里的时候是否是就很清晰了呢?