Android回調解惑

Android回調解惑,對於Android的回調,我相信凡是隻要是開發過Android的,必然會碰到。但是我想大傢對於這個名詞都會是一個慢慢理解的過程,我也是一樣,一開始肯定是迷茫的,特別是小白。

經過實踐的洗禮,一遍一遍的cv,到後來自己慢慢深入理解,最後終於理解瞭這個過程。就是一個門外門裡的感覺,一旦真正理解瞭,就會覺得非常簡單,迷茫到解惑其實隻是一步之遙,就看你能否跨過。這個道理也不僅局限於此,時間萬物也都是如此,隻要不畏懼,你就能把他拿下。

我想此事在看的讀者,也肯定查看過很多的資料。一般都會看到一個對回調的比喻:

我打電話給小明,有一個問題想問他,但是接通後,他說現在很忙,需要處理完事後再幫你解決這個問題,最後會打電話到訴我答案。

如我我在什麼都不懂的情況下,看到這個比如是懵逼的。但我們還是要硬著頭皮去慢慢理解,我相信最後將是取得成功的。

話不多說,那我們就以此為例子,通過代碼的方式,還原回調的過程。

首先是最最最重要的代碼,是回調的精華所在,即定義一個接口,此接口的作用我先說下:就是作為一個動作的回撥,下面會介紹到

package com.pyj.myapplication.huidiao;

/**
 * 作為一個回撥的作用
 *
 * @author: 流冥
 * @date: 2017-08-02 16:12
 */
public interface IAsk {

    //告知答案
    void tellAnswer(String answer);

}

接下來是小明粉墨登場

package com.pyj.myapplication.huidiao;

/**
 * 小明的一系列行為操作
 *
 * @author: 流冥
 * @date: 2017-08-02 16:25
 */
public class Xiaoming {
    IAsk iAsk;
    String question;//問題
    String answer;//答案

    public Xiaoming(IAsk iAsk) {
        this.iAsk = iAsk;
    }

    //聯系小明的方式,通過電話的方式找到小明,並且問出一個問題
    public void callMe(String question) {
        this.question = question;
        System.out.println(question);
    }

    //小明在外面辦事,暫時沒時間
    public void doSomeThing() {
        for (int i = 0; i < 3; i++)
            System.out.println("小明在辦第" + i + "件事");
        System.out.println("小明處理完自己的事");
        
    }

    //小明對於這個問題的思考並且想到瞭答案
    public void thinkQuestionAndGetAnswer() {
        System.out.println("小明開始思考-----" + question + "------這個問題");
        answer = "2";
        System.out.println("小明想到答案是----" + answer);
    }

    //小明想通瞭這個問題,並聯系到我把答案告訴瞭我
    public void callPeoson() {
        iAsk.tellAnswer("小流,答案是" + answer + ",這麼簡單的都不會,你自己要好好反思瞭哦!");
    }


}

接下來是整個場景,以我為第一個人稱開始的表演:

package com.pyj.myapplication.huidiao;

/**
 * 場景再現
 *
 * @author: 流冥
 * @date: 2017-08-02 16:15
 */
public class CallBackTest {
    //這個場景是站在我的立場上,小明是第二人稱
    public static void main(String[] args) {
        //這裡的IAsk,就像是我的手機號碼一樣,當小明想到答案瞭,就會通過iAsk這個對象來聯系我,並把答案告訴我
        Xiaoming xiaoming = new Xiaoming(new IAsk() {//找到小明,並告訴他我的聯系方式,回頭想到瞭答案可以聯系我
            @Override
            public void tellAnswer(String answer) {
                System.out.println(answer);
            }
        });
        xiaoming.callMe("小明,我有個問題要問你,1+1等於多少?");//打電話給小明,問他問題
        xiaoming.doSomeThing();//小明有事,先做完他自己的事
        xiaoming.thinkQuestionAndGetAnswer();//小明做完自己的事後,開始思考問題並最終想到答案
        xiaoming.callPeoson();//小明通過我之前留給他的聯系方式,告訴我他得到的答案,並勸誡我要好好學習瞭
    }


}

回調,顧名思義,有來有回,大傢記住,來而不往非禮也,此時,我覺得對於回調來說無比貼切。

接下來開始慢慢分析:

	Xiaoming xiaoming = new Xiaoming(new IAsk() {//找到小明,並告訴他我的聯系方式,回頭想到瞭答案可以聯系我
            @Override
            public void tellAnswer(String answer) {
                System.out.println(answer);
            }
        });

一開始我new瞭小明一個對象,並把IAsk這個參數傳給瞭小明。我們用情景的方式來描述的話,就是:此時此刻,我打電話找打瞭小明,並告知他我的聯系方式(即IAsk),這一步其實也是最重要的一步,這裡已經有2個大人物出現瞭,小明和我的聯系方式(IAsk),這2個就像是動漫裡經常提到的羈絆,相互關聯著。有瞭這層聯系,後面發生的一系列事才會得到答案。

 	xiaoming.callMe("小明,我有個問題要問你,1+1等於多少?");//打電話給小明,問他問題
        xiaoming.doSomeThing();//小明有事,先做完他自己的事
        xiaoming.thinkQuestionAndGetAnswer();//小明做完自己的事後,開始思考問題並最終想到答案

這些就是我在打通小明後,小明做的一系列的事,顯示幹完自己的事,然後思考我的問題並相處答案。像這樣的場景,在寫代碼的過程中很多,

比方在receyleView的適配器中,先讓其展示,當用戶點擊某個item的時候,觸發點擊事件,回傳到activity並把點擊的信息一並傳遞過去;

又或者最經典的button點擊事件,我先放一個按鈕,我不知道按鈕什麼時候會被點擊,但是我知道一定是用戶點擊的時候,點擊事件才會發生,此時我們建立一個回調,等用戶點擊的時候返回給我點擊信息。

就如同小明想到答案瞭再打電話告訴我一般。這樣一來,是否會更好理解瞭呢。

最後,就是小明回撥電話給我瞭

xiaoming.callPeoson();//小明通過我之前留給他的聯系方式,告訴我他得到的答案,並勸誡我要好好學習瞭

這個操作一旦完成,在IAsk裡的tellAnswer(String answer)方法就會接收到小明給我的答案瞭。

最後打印下整個日志
 

小明,我有個問題要問你,1+1等於多少?
小明在辦第0件事
小明在辦第1件事
小明在辦第2件事
小明處理完自己的事
小明開始思考-----小明,我有個問題要問你,1+1等於多少?------這個問題
小明想到答案是----2
小流,答案是2,這麼簡單的都不會,你自己要好好反思瞭哦!

如果有小夥伴不明白為什麼xiaoming.callPeoson()這個方法一執行tellAnswerString answer)這個方法就會被調用的話,你就要好好理解下java的interface和實現過程。

其實也是很簡單的,

Xiaoming xiaoming = new Xiaoming(new IAsk() {//找到小明,並告訴他我的聯系方式,回頭想到瞭答案可以聯系我
            @Override
            public void tellAnswer(String answer) {
                System.out.println(answer);
            }
        });

我們在xiaoming的構造函數中傳遞瞭一個IAsk的實現類,就說明xiaoming已經擁有這個實現類的對象,之後,隻要隻要調用這個實現類的方法,這個方法就必然會執行。

其實這也就是java的多態性而已,不懂的要去好好理解下多態的概念吧

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *