Android 的回調(diào)事件詳解
看見網(wǎng)上一些回調(diào)的解釋都很復(fù)雜的,特別基于Android的自定義回調(diào),感覺一頭霧水,于是乎,我也寫了這篇基于我對(duì)回調(diào)的解釋。
先來看一個(gè)簡單的例子:
有兩個(gè)類 ClassA ,和 ClassB, ClassA調(diào)用ClassB里面的方法,
public class ClassB { public void method_from_classB(){ for(int i=0;i<10;i++) System.out.print("..."+i); } } public class ClassA { public static void main(String args[]){ ClassB classB = new ClassB(); classB.method_from_classB(); } }
輸出:
...0...1...2...3...4...5...6...7...8...9
臥槽,哪個(gè)傻逼寫的博文,侮辱我的智商不是嗎,嘻嘻,是為了做比較,接下來看看利用回調(diào), ClassA 是怎么調(diào)用 ClassB中的 方法的,注意是回調(diào):
讓ClassB 實(shí)現(xiàn) ClassA定義的接口
public class ClassB implements ClassA.ClassAInterface{ public ClassB(){ new ClassA().RegisterInterface(this); System.out.println("...ClassB..."+this); } @Override public void method_from_interface() { for(int i=0;i<10;i++) System.out.print("..."+i); } /* public void method_from_classB(){ for(int i=0;i<10;i++) System.out.print("..."+i); }*/ }
ClassA里面定義接口和抽象方法:
public class ClassA { public static ClassAInterface classAInterface; public interface ClassAInterface{ public void method_from_interface(); } public void RegisterInterface(ClassAInterface a_interface){ this.classAInterface = a_interface; System.out.println("...a_interface..."+a_interface); } public static void main(String args[]){ ClassB classB = new ClassB();// 標(biāo)記@1,最后面做解釋 //classB.method_from_classB(); System.out.println("...classAInterface..."+classAInterface); if(classAInterface != null){ classAInterface.method_from_interface(); } } }
輸出:
...0...1...2...3...4...5...6...7...8...9
整理下,也就是 我在ClassA里面定義了一個(gè)接口(interface),接口里面又定義了一個(gè)方法,但沒有方法體,也就不做任何事情。
當(dāng) ClassA 執(zhí)行到 mian() 函數(shù)時(shí),就會(huì)調(diào)用接口的方法,但前面講了,接口的方法沒有實(shí)現(xiàn)具體的事情,它就會(huì)找到 ClassB 里面對(duì)應(yīng)的 方法,來實(shí)現(xiàn)具體的事情。
呦呦呦,ClassA 的接口的方法是怎么找到 ClassB 的方法,難道會(huì)上天???
也就是下面分析這句代碼是怎么上天的:
// 利用接口的回調(diào)實(shí)現(xiàn) ClassB中 的方法的 具體事情
classAInterface.method_from_interface();
我在上面的代碼中用 System.out.println 打印出了日志做分析:
第一個(gè)(ClassA中的方法):
public void RegisterInterface(ClassAInterface a_interface){ this.classAInterface = a_interface; System.out.println("...a_interface..."+a_interface); }
輸出:
...a_interface...ClassB@3ddb8962
第二個(gè):
public ClassB(){ new ClassA().RegisterInterface(this); System.out.println("...ClassB..."+this); }
輸出:
...ClassB...ClassB@3ddb8962
第三個(gè):
System.out.println("...classAInterface..."+classAInterface); if(classAInterface != null){ classAInterface.method_from_interface(); }
輸出:
...classAInterface...ClassB@3ddb8962
看到這里是不是恍然大悟呢 ,輸出都是 “ ClassB@3ddb8962 ” 也就是ClassB 對(duì)象的引用?。?!
啊!接口只不過是將 ClassB 對(duì)象的引用 傳到 ClassA中而已,那這句會(huì)上天的語句是不是很好解釋了呢。
classAInterface.method_from_interface();
相當(dāng)于 ClassB@3ddb8962.method_from_interface();
這是不是跟最上面到的代碼:
ClassB classB = new ClassB(); classB.method_from_classB();
一樣呢,這也是為什么我最開始要舉這個(gè)例子的原因?。?!
相信看到這里應(yīng)該理解了接口的回調(diào)是怎么回事了吧。
但有一點(diǎn)又糊涂了,為什么 要接口回調(diào)這么麻煩的,最上面的在ClassA里面執(zhí)行:
ClassB classB = new ClassB(); classB.method_from_classB();
不是照樣可以 ClassA 調(diào)用 ClassB 里面的 方法。。。。但要是ClassA 要調(diào)用ClassC,ClassD ...,里面的方法呢,是不是還要改變ClassA里面的代碼,實(shí)例化ClassC,ClassD ... 的對(duì)象,顯然是不好的,要是使用接口那就不用改變ClassA 里面的代碼了,任何類只要實(shí)現(xiàn)ClassA 里面的接口就可以.
解釋一下 標(biāo)記@1 :
上面那段話好像跟 標(biāo)記@1 違背了,在 ClassA 里面確實(shí)也需要實(shí)例化 ClassB對(duì)象。
因?yàn)橐?【利用】 初始化的時(shí)候執(zhí)行構(gòu)造方法里面的代碼:
public ClassB(){ // 相當(dāng)于回調(diào)事件的注冊(cè),初學(xué)者出現(xiàn)回調(diào)空指針很有可能這邊忘記‘注冊(cè)'了 new ClassA().RegisterInterface(this); }
將this 傳遞給 ClassA ,作用也就是 上面利用 日志分析的作用。
但再 Android 開發(fā)中救你不必這樣了,
可以在 Activity 的初始化時(shí)執(zhí)行:
@Override protected void onCreate(Bundle savedInstanceState) { // 相當(dāng)于回調(diào)事件的注冊(cè),初學(xué)者出現(xiàn)回調(diào)空指針很有可能這邊忘記‘注冊(cè)'了 new ClassA().RegisterInterface(this); }
在Android 開發(fā)中 ClassA 里面的 mian() 函數(shù)可以用事件來代替,觸發(fā):
如:
button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO 自動(dòng)生成的方法存根 if(classAInterface != null){ classAInterface.method_from_interface(); } });
- Android中Fragment多層嵌套時(shí)onActivityResult無法正確回調(diào)問題的解決方法
- Android異步回調(diào)中的UI同步性問題分析
- Android的Fragment的生命周期各狀態(tài)和回調(diào)函數(shù)使用
- 深入淺析Android接口回調(diào)機(jī)制
- 理解Android中Activity的方法回調(diào)
- android自定義控件和自定義回調(diào)函數(shù)步驟示例
- 詳細(xì)介紹Android中回調(diào)函數(shù)機(jī)制
- Android中回調(diào)接口的使用介紹
- 基于Android中Webview使用自定義的javascript進(jìn)行回調(diào)的問題詳解
- Android 回調(diào)詳解及簡單實(shí)例
相關(guān)文章
Android中使用 AutoCompleteTextView 實(shí)現(xiàn)手機(jī)號(hào)格式化附帶清空歷史的操作
有個(gè)小伙伴遇到了這樣一個(gè)問題,就是AutoCompleteTextView實(shí)現(xiàn)自動(dòng)填充的功能。同時(shí)要具備手機(jī)格式化的功能。接下來通過本文給大家分享使用 AutoCompleteTextView 實(shí)現(xiàn)手機(jī)號(hào)格式化附帶清空歷史的操作方法,需要的朋友參考下2017-03-03Android ScrollView實(shí)現(xiàn)橫向和豎向拖動(dòng)回彈效果
這篇文章主要為大家詳細(xì)介紹了Android ScrollView實(shí)現(xiàn)橫向和豎向拖動(dòng)回彈效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09用Android?studio實(shí)現(xiàn)簡易計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了用Android?studio實(shí)現(xiàn)簡易計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Android 實(shí)現(xiàn)永久保存數(shù)據(jù)的方法詳解
本篇文章是對(duì)Android實(shí)現(xiàn)永久保存數(shù)據(jù)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android開發(fā)筆記 今天學(xué)到的一些屬性
離開實(shí)驗(yàn)室之前再貼上今天下午自己學(xué)到的一些基礎(chǔ)知識(shí) 上午干嘛了呢,忙著數(shù)據(jù)恢復(fù)呢2012-11-11Android中使用Notification實(shí)現(xiàn)狀態(tài)欄的通知
本文主要介紹了android利用Notification實(shí)現(xiàn)狀態(tài)欄的通知的示例代碼。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04android監(jiān)控sim卡有沒有服務(wù)示例(sim卡管理)
android監(jiān)聽SIM卡有沒有服務(wù),可以使用android.telephony.PhoneStateListener類來實(shí)現(xiàn),下面是一個(gè)簡單的小例子,大家參考使用吧2014-01-01Android SD卡上文件操作及記錄日志操作實(shí)例分析
這篇文章主要介紹了Android SD卡上文件操作及記錄日志操作的方法,涉及Android針對(duì)SD卡與文件操作的相關(guān)技巧,需要的朋友可以參考下2016-01-01