1. 程式人生 > >Java和Android回撥機制

Java和Android回撥機制

回撥介紹

所謂回撥,就是客戶程式Client呼叫服務程式Service中的某個方法A,然後Service又在某個時候反過來呼叫Client中的某個方法B,對於Client來說,這個B便叫做回撥函式。 
這裡寫圖片描述

回撥的如何實現的呢

Java的回撥是通過介面或者內部類來實現的。

JAVA方法回撥是功能定義和功能實現分享的一種手段,是一種耦合設計思想。作為一種架構,必須有自己的執行環境,並且提供使用者的實現介面。

程式碼案例

這裡就上面的講解寫一個最簡單的例子: 
第一步:因為方法的回撥是通過介面來實現的所以要定義一個介面(我們稱它為回撥介面)

/**
 * 定義一個回撥介面,包含一個回撥函式
 * @author Administrator
 */
public interface CallBack {
    /**
     * 這就是Service回撥Client的方法
     * @param result 回撥時攜帶的引數(可選)
     */
    public void B(String result);
}

/**
 * 這個Client類, 實現CallBack介面(條件一)
 * @author Administrator
 *
 */
public class Client implements CallBack{

    /**
     * Client類 包含 Service類 的引用 (條件二)  因為Client要呼叫Service中的方法
     */
    Service service = new Service();//可直接例項化或在建構函式或某個方法中進行例項化

    /**
     * 該方法用於請求Service呼叫Service中的方法
     */
    public void requrst(){
        System.out.println("請求伺服器呼叫伺服器的方法");
        service.A(this);//傳入當前物件也就是CallBack物件,因為Client實現類CallBack介面
    }



    /**
     * Service回撥Client的實現方法
     */
    @Override
    public void B(String result) {
        // TODO Auto-generated method stub
        System.out.println("伺服器回撥我的方法返回的結果是:"+result);
    }

}
public class Service {

    CallBack callback;//定義介面型別物件,要呼叫介面中的回撥方法

    String result = "謝謝你的請求";

    public void sendManage(Client client) {
        this.callback = client;
        callback.B(result);//呼叫的是該介面的實現方法(即Client中的B)
    }


}

測試類
public class Test {
    public static void main(String[] args) {
        Client client = new Client();
        client.requrst();
    }
}

輸出結果:

請求伺服器呼叫伺服器的方法 
伺服器回撥我的方法返回的結果是:謝謝你的請求

回撥實現的步驟

以上就是一個簡單實現介面回撥的機制,我們總結一下實現的所需的步驟: 
1、定義回撥介面和回撥方法 
2、Client實現回撥介面和回撥方法,並在Client中包含Service引用,通過引用呼叫Servie中的方法並且必須傳入一個當前物件Client(因為當前物件實現了CallBack介面所以也屬於介面物件
3、在Service中定義一個介面物件並在方法中對初始化(將Client傳過來的當前物件賦值給介面物件),通過介面物件呼叫介面中方法(呼叫的Client實現的介面方法) 
4、測試

回撥的綜合案例(非同步+回撥)

以下一個比較綜合的例子使用到了“非同步+回撥” 
比如生活中的例項,某天,我打電話向你請教問題,當然是個難題,^_^,你一時想不出解決方法,我又不能拿著電話在那裡傻等,於是我們約定:等你想出辦法後打手機通知我,這樣,我就掛掉電話辦其它事情去了。過了XX分鐘,我的手機響了,你興高采烈的說問題已經搞定,應該如此這般處理。 
故事到此結束。這個例子說明了“非同步+回撥”的程式設計模式。其中,你後來打手機告訴我結果便是一個“回撥”過程,結果(即處理方法)就是一個回撥函式。 
我的手機號碼必須在以前告訴你,即告訴你通過何種方式可以找到我,這便是註冊回撥函式;我的手機號碼應該有效並且手機能夠接收到你的呼叫,這是回撥函式必須符合介面規範。

案例實現介面回撥的步驟: 
1.定義一個回撥介面包含回撥方法(這是介面約定,有答案時電話聯絡) 
2.我(Me.java)這個類實現回撥介面和提供回撥方法的實現,並向你註冊回撥(因為只有向你註冊了回撥你才能回撥我的方法告訴我答案) 
3.你(You.java)這個類提供了接收問題並回答(回答就是我向你註冊的回撥引數型別為介面物件)的方法 
4.測試類

/**
 * 定義一個回撥介面,包含一個回撥函式
 * @author Administrator
 */
public interface CallBack {
    /**
     * 當你知道答案可以呼叫該回調函式告訴我答案
     * @param result 答案
     */
    public void solve(String result);
}
/**
 * 這個類代表我,因為你要告訴我答案所以要實現CallBack回撥介面和介面中的回撥方法的實現
 * 我要向你提問所以有一個提問的方法askQqstion(),在提問的同時要向對方(你)註冊回撥介面,當你知道答案的時候呼叫我裡面的介面實現方法,最後得到答案
 * @author Administrator
 *
 */
public class Me implements CallBack{

    /**
     * 我(Me)這裡包含一個對你(You)的引用
     * 因為我(Me)要呼叫你(You)裡面的方法向你詢問(問題的描述)和註冊回撥(用於你告訴我答案)
     */
    private You you;

    public Me(You you){
        this.you = you;     //例項化引用
    }


    /**
     * 我通過這個方法向你進行提問,在提問時進行回撥註冊,讓你在知道答案是可以告訴我
     * @param question  問題的描述
     */
    public void askQqstion(final String question){

        //非同步
        new Thread(new Runnable() {

            @Override
            public void run() {
                /**
                 * 我呼叫你的方法,在這裡向你註冊回撥介面
                 */
                you.executeMessage(Me.this, question);              
            }
        }).start();     
    }   


    // 我問完問題後就掛掉電話,讓你去思考問題的答案同時我也可以去做別的事
    public void play(){
        System.out.println("我去完了");
    }


    /**
     *當你知道答案後呼叫此方法告訴我,就是所謂的回撥方法
     */
    @Override
    public void solve(String result) {
        System.out.println("你告訴我的答案是--->"+result);
    }
}
public class You {

    /**
     * 接收我的問題和基友回答問題的
     * @param callBack 介面回撥物件,通過該物件可以呼叫實現了該介面的物件(Me)中的介面實現方法(Me中的solve()方法)
     * @param question 問題描述
     */
    public void executeMessage(CallBack callBack, String question){

        //模擬你要思考很長時間
        for(int i=0;i<10000;i++){

        }   


        /**
         * 想到了答案
         */
        String result = "答案就是我也不知道";    


        /**
         * 想到後你就打電話告訴我,放過來呼叫我這個類中的回撥方法
         */
        callBack.solve(result);     
    }
}
/**
 * 測試類
 * @author Administrator
 *
 */
public class Test {

    public static void main(String[] args) {
        //兩個物件一個我一個你
        You you = new You();
        Me me = new Me(you);

        //我向你提問
        me.askQqstion("世界到底有多大?");
    }
}

輸出結果:

你告訴我的答案是—>答案就是我也不知道

回撥函式(方法)小總結:

1.回撥函式也是一個函式或過程,不過它是一個由呼叫方自己實現,供被呼叫方使用的特殊函式。 
2.即呼叫方A不直接使用此函式function,而是通過呼叫被呼叫方B來間接呼叫function。

通過上面的那個例子你是不是差不多明白了回撥機制呢,上面是一個非同步回撥,就是我去做我的事但是我還是在等你的答案,相應的也有同步回撥。執行緒run()也是一個回撥方法,當執行Thread的start()方法就會回撥這個run()方法,還有處理訊息都比較經典等等

Android中的回撥機制

比較笨的一種認識:Android中以on開頭的方法都是回撥方法:onCreate (),onStart (),onPause (),onStop()等等。 
在Activity中定義了很多生命週期的不同狀態要呼叫的方法,這些方法都是空實現,系統框架要呼叫,使用者也要呼叫來實現。 
1.以上可以看出,介面(系統框架)是系統提供的,介面的實現是使用者實現的,這樣可以達到介面統一,實現不同的效果。    
2.系統在不同的狀態“回撥”我們的實現類,來達到介面和實現的分類。