某天,我打電話向你請教問題,固然是個難題,你一時想不出解決方法,我又不能拿着電話在那裏傻等,因而咱們約定:等你想出辦法後打手機通知我,這樣,我就掛掉電話辦其它事情去了。過了XX分鐘,個人手機響了,你興高采烈的說問題已經搞定,應該如此這般處理。java
這就是一個典型的回調過程。android

C不會本身調用b,C提供b的目的就是讓S來調用它,並且C不得不提供。S並不知道C提供的b是什麼,所以S會約定b的接口規範(函數原型),而後由C提早經過S的一個函數r告訴S本身將要使用b函數(即註冊)。r爲註冊函數。編程
簡單來講:服務器
回調函數就是預留給系統調用的函數,並且咱們每每知道該函數被調用的時機異步
好的,繼續完善下上面的那幅圖。ide

生活中處處都有回調這種思想存在。軟件的不少思想其實只是咱們實際生活中思惟方式的一種轉化。函數
再將一個小故事:post
咱們平時考試答題的第一件事是幹嗎?沒錯,是寫上學號和姓名。這裏注意了,咱們填寫學號和姓名不是給本身看的(即該方法不是給本身調用的),而是給老師登記分數時看的(預留給系統未來調用),這其實就是一個回調的應用。老師提供接口(輸入姓名,學號規則),咱們利用接口註冊。
看到上面的小故事,你們對回調就有了一些瞭解了,咱們再回到開頭的那個小故事。
那個故事說明了「異步+回調」的編程模式。其中,你後來打手機告訴我結果即是一個「回調」過程;個人手機號碼必須在之前告訴你,這即是註冊回調函數;個人手機號碼應該有效而且手機可以接收到你的呼叫,這是回調函數必須符合接口規範。
知道了回調的基本流程,下面,來看看Android中回調的基本使用。this
場景一:spa
- Button button = (Button)this.findViewById(R.id.button);
- button.setOnClickListener(newButton.OnClickListener() {
-
- @override
- publicvoidonClick(View v) {
- buttonTextView.setText("按鈕被點擊了");
- }
- });
上面的代碼給按鈕加了一個事件監聽器,這其實就是「回調」最多見的應用場景之一。咱們本身不會顯式地去調用onClick方法。用戶觸發了該按鈕的點擊事件後,它會由Android系統來自動調用。
熟悉的組件,熟悉的監聽器。。。
場景二:
- @Override
- publicvoidonCreate(BundlesaveInstanceState) {
- super.onCreate(saveInstanceState);
-
- }
- @Override
- publicvoidonResume() {
- super.onResume();
-
- }
Activity的整個生命週期基本上都說回調函數在發揮做用。
好了,看了兩個咱們常常使用的回調方式,來總結下android利用回調的基本方法。其實,只是把咱們的那張圖翻譯了下。
首先,服務器端建立一個回調接口
- public interface ICallBack {
- void postExec();
- }
- public class FooBar {
- private ICallBackcallBack;
- public void setCallBack(ICallBackcallBack) {
- this.callBack =callBack;
- }
- public void doSth() {
- callBack.postExec();
- }
- }
- public class Test {
- public static void main(String[] args) {
- FooBarfoo = newFooBar();
- foo.setCallBack(newICallBack() {
- public void postExec() {
- System.out.println("method executed.");
- }
- });
- foo.doSth();
- }
- }
對回調的深刻思考:
程序的本質就是代碼跳轉,無論同步異步反射接口虛函數,本質上都是函數調用。函數咱們要調用它,就須要它的指針,不一樣語言經過不一樣的方式來獲得這個指針。而咱們定義的接口其實就是一個函數指針,那麼那個註冊過程,其實就是至關於對那個函數指針賦值。經過這個函數指針來調用咱們定義的自實現函數。