Java 基礎複習實踐 --- CallBack

很早以前不知道如何解釋清楚回調函數(CallBack),在知乎上看到一個回答特別形象,當時就收藏了,因此今天決定用代碼的形式再讓這個回答更加深入點。ide

知乎-回調函數(callback)是什麼?函數

而後再看看 Android 裏的應用。this

什麼是回調函數

維基的解釋:對象

在計算機程序設計中,回調函數,或簡稱回調(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();
    }

}

Android 裏常見的回調

咱們常常這樣寫:

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);
}

到這裏的時候是否是就很清晰了呢?

相關文章
相關標籤/搜索