很早以前不知道如何解釋清楚回調函數(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); }
到這裏的時候是否是就很清晰了呢?