淺談回調接口

序言

有需求,才會去創造。
網絡上有許多關于接口回調的文章,各有千秋,理解角度也分別不同。今天本人希望從需求角度,能讓一些對于接口回調不了解,或者概念模糊的人理解一下。本來是想寫一下回調的概念。但是我發現這樣不利于理解,所以這里我就不贅述概念了,大家看這篇博文也不要帶著固定的思維去理解,希望大家舉一反三吧。這里我從一個需求的角度讓大家理解一下回調的邏輯流程。

目的

java中接口回調隨處可見,比如說各種監聽,onClickListener,而最近比較熱的Mvp框架,其中view層抽象接口,也屬于接口回調,掌握他,你會發現,邏輯世界還是很神奇的。

應用場景

  1. 多線程之間數據同步問題
    更具象的說法,舉個例子,我前段日子有個需求,我需要處理一些字段,但是這些字段里有一個值是北京時間,而北京時間是需要異步獲取,這樣我希望的就是獲取到北京時間后,再處理。這里我就用了接口回調。 (ps:這里我將需求盡可能的簡化,只是為了讓大家理解回調流程,詳細的需求是加密驗證,這里就不詳述了!否則有點本末倒置。)

流程示范


編寫功能模塊

功能類A

package com.dong.test;

/**
 *
 * @author JDD 這是一個功能類 假設他用來處理一些字段
 *
 */
public class ManageFields {
    String str;
    /**
     * 用來處理字段的方法,而其中有一個字段是北京時間,需要開啟異步線程獲取時間后再進行一些邏輯處理
     */
    public void doSomething(String string) {
        //這里我需要獲取北京時間,處理的話比如說拼接一段字段在北京時間前面
         str = string;
        //現在要獲取北京時間,這個就是開啟一個異步線程去獲取,現在問題來了怎么獲取它得到的異步時間并拼接起來的。這里就用到了回調
        TimeUtil timeUtil = new TimeUtil();
        timeUtil.getBjTime();
    }
}

功能類B

package com.dong.test;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

/**
 *
 * @author JDD 這個是個時間類 需要獲取北京時間
 *
 */
public class TimeUtil {

    /**
     * 開啟異步線程去獲取時間
     */
    public void getBjTime() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                URL url;
                try {
                    url = new URL("http://www.baidu.com");
                    URLConnection uc = url.openConnection();// 生成連接對象
                    uc.connect(); // 發出連接
                    long ld = uc.getDate(); // 取得網站日期時間
                    Date date = new Date(ld); // 轉換為標準時間對象
                    // 分別取得時間中的小時,分鐘和秒,并輸出
                    long bjTime = date.getTime();

                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } // 取得資源對象
                catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
    }

}

So 問題來了,該怎將獲取的時間同步給A呢?這里大家可以發散一下思維,onclick事件,觸發機制,也就是回調機制,它是完成點擊(獲取到時間后),執行回調函數 onClick(view v)(執行處理操作)。那這里我們將回調時間抽象成接口。

編寫接口

回調時間抽象成接口。

抽象接口

package com.dong.test;

/**
 *
 * @author JDD 時間回調接口 或者說就是監聽時間獲取
 *
 */
public interface TimeListener {
    //抽象方法,其中參數 就是獲取到的時間
    void returnTime(long bjTime);
}```

## 改造模塊實現回調 ##
首先時間獲取模塊B中應該有一個實現了TimeListener對象的引用,這里我們去重載一下其構造函數

package com.dong.test;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

/**

  • @author JDD 這個是個時間類 需要獲取北京時間

*/
public class TimeUtil {

TimeListener timeListener;
/**
 * 這個是實現了TimeListener的對象的引用(其實就是ManageFileds的引用,這樣就需要ManageFields類去實現接口)
 * @param timeListener
 */
public TimeUtil(TimeListener timeListener){
    this.timeListener=timeListener;
}

/**
 * 開啟異步線程去獲取時間
 */
public  void getBjTime() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            URL url;
            try {
                url = new URL("http://www.baidu.com");
                URLConnection uc = url.openConnection();// 生成連接對象
                uc.connect(); // 發出連接
                long ld = uc.getDate(); // 取得網站日期時間
                Date date = new Date(ld); // 轉換為標準時間對象
                // 分別取得時間中的小時,分鐘和秒,并輸出
                long bjTime = date.getTime();
                //調用管理時間的接口
                timeListener.returnTime(bjTime);

            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } // 取得資源對象
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }).start();
}

}


管理字段的類就需要實現 TimeListener接口

package com.dong.test;

/**

  • @author JDD 這是一個功能類 假設他用來處理一些字段

/
public class ManageFields implements TimeListener {
String str;
/
*
* 用來處理字段的方法,而其中有一個字段是北京時間,需要開啟異步線程獲取時間后再進行一些邏輯處理
*/
public void doSomething(String string) {
// 這里我需要獲取北京時間,處理的話比如說拼接一段字段在北京時間前面
str = string;
// 現在要獲取北京時間,這個就是開啟一個異步線程去獲取,并將this,也就是自己的引用傳過去
TimeUtil timeUtil = new TimeUtil(this);
timeUtil.getBjTime();
}

/**
 * 這里就是當異步線程獲取到數據,調用timeListener.returnTime(bjTime)時,所回調的方法
 */
@Override
public void returnTime(long bjTime) {
    // TODO Auto-generated method stub
    System.out.println(str+bjTime);
}

}



## 測試代碼 ##

package com.dong.test;

public class TestCallBack {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    ManageFields manageFields1=new ManageFields();
    ManageFields manageFields2=new ManageFields();

    manageFields1.doSomething("現在北京時間是:");
    manageFields2.doSomething("Now BeiJingTime is:");


}

}

結果
Now BeiJingTime is:1459396779000
現在北京時間是:1459396780000

## 流程圖 ##
下面你有個大概思路了,我們看一下流程圖(viso制作)

![流程圖](http://upload-images.jianshu.io/upload_images/1606094-691494792db957eb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 拓展 ##
當然 管理字段類還可以寫成大家熟知的匿名內部類形式

package com.dong.test;

/**

  • @author JDD 這是一個功能類 假設他用來處理一些字段

*/
public class ManageFields {
String str;
//匿名內部類實現
public void doSomething(String string) {
// 這里我需要獲取北京時間,處理的話比如說拼接一段字段在北京時間前面
str = string;
// 現在要獲取北京時間,這個就是開啟一個異步線程去獲取,并將this,也就是自己的引用傳過去
TimeUtil timeUtil = new TimeUtil(new TimeListener() {

        @Override
        public void returnTime(long bjTime) {
            // TODO Auto-generated method stub
            System.out.println(str+bjTime);
        }
    });
    timeUtil.getBjTime();
}

}


## 后話 ##
當然,你要是了解Rxjava,或者觀察者模式,抑或handler等,都是可以實現這種需求的,但是,總有一種場景,有一種工具更配的來。就跟工具箱里的扳手一樣,你有很多扳手,但是也有不同的螺絲,匹配的來的工具不是更給力么!
然而回調有時候不是必須的,因為有一個問題就是callbackhell-回調地獄,我的認知就是由于各種回調嵌套,導致工程可讀性,可塑性差。所以大家也要兩面性的看待問題!
## 源碼 ##
[接口回調樣例源碼](http://7xsffo.com1.z0.glb.clouddn.com/TestCallBack.rar "接口回調樣例源碼")
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,761評論 25 708
  • 點擊查看原文 Web SDK 開發手冊 SDK 概述 網易云信 SDK 為 Web 應用提供一個完善的 IM 系統...
    layjoy閱讀 13,854評論 0 15
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,737評論 18 399
  • http://www.cnblogs.com/zangwucao/p/5505331.html https://m...
    灰客閱讀 438評論 0 1
  • 今天持續學習英語的第23天,感覺已經走了很多路,但掰掰手指頭,發現起點還在地平線上。加入“日拱一卒”社群,這個終于...
    不完美世界閱讀 536評論 0 0