接口回調(diào)是指:
可以把使用實(shí)現(xiàn)了某一接口的類創(chuàng)建的對(duì)象的引用崇呵,賦給該接口聲明的接口變量骆膝,那么該接口變量就可以調(diào)用被類實(shí)現(xiàn)的接口的方法蛮瞄。實(shí)際上浴井,當(dāng)接口變量調(diào)用被類實(shí)現(xiàn)的接口中的方法時(shí)久脯,就是通知相應(yīng)的對(duì)象調(diào)用接口的方法纳胧,這一過(guò)程稱為對(duì)象功能的接口回調(diào)。
以上一篇“ListView滑動(dòng)到底部加載更多內(nèi)容”為例:
1.下面是自定義ListView中的部分代碼:
//聲明接口變量
ILoadListener iLoadListener;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//當(dāng)滾到最后一行且停止?jié)L動(dòng)時(shí)帘撰,顯示布局跑慕,加載數(shù)據(jù)
if(isLastRow && scrollState == SCROLL_STATE_IDLE){
if(!isLoading){
isLoading = true;
footer.findViewById(R.id.load_layout).setVisibility(View.VISIBLE);
//接口回調(diào)(接口變量調(diào)用接口中的方法,而這個(gè)方法被接口的實(shí)現(xiàn)類摧找,即此處的主Activity復(fù)寫過(guò)了核行,所以相當(dāng)于通知主Activity的對(duì)象調(diào)用接口中被自己復(fù)寫過(guò)的方法)
iLoadListener.onLoad();
}
}
}
//相比而言,這就是自定義ListView一個(gè)普通函數(shù)了蹬耘。
//如果你搞不明白這個(gè)函數(shù)的意義芝雪,你只要想一想,這個(gè)函數(shù)的作用是什么:“將傳入的ILoadListener類型的對(duì)象综苔,設(shè)置為自定義ListView中最上面聲明的接口變量(調(diào)用onLoad方法的那個(gè)變量)”
public void setInterface(ILoadListener iLoadListener){
this.iLoadListener = iLoadListener;
}
//讓主Activity去實(shí)現(xiàn)這個(gè)接口惩系,然后復(fù)寫接口中定義的空的onLoad方法。
//什么情況下用接口回調(diào)呢如筛?聽過(guò)一句話:“你(此處主Activity)想讓別人(此處的自定義ListView)的代碼執(zhí)行你的代碼堡牡,而別人的代碼你又不能動(dòng)”
//此處定義接口
public interface ILoadListener{
public void onLoad();
}
2.下面是主Activity中的部分代碼(這個(gè)Activity實(shí)現(xiàn)了ILoadListener接口):
private void showListView(ArrayList<ApkEntity> apk_list) {
if (adapter == null) {
listView = (LoadListView) findViewById(R.id.id_listView);
//意思就是,我們的主activity對(duì)象(this)妙黍,就是自定義ListView中最上面聲明的接口變量悴侵,就是調(diào)用onLoad接口函數(shù)的那個(gè)對(duì)象
listView.setInterface(this);
adapter = new MyAdapter(this, apk_list);
listView.setAdapter(adapter);
}else{
adapter.onDateChange(apk_list);
}
}
//因?yàn)閷?shí)現(xiàn)了接口瞧剖,所以復(fù)寫接口的方法
@Override
public void onLoad() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
getLoadData();
showListView(apk_list);
listView.loadComplete();
}
}, 2000);
}
指導(dǎo)思想:
面向?qū)ο笤O(shè)計(jì)的封裝性拭嫁,模塊間要解耦,模塊內(nèi)要內(nèi)聚
關(guān)鍵字:解耦
削弱模塊間的協(xié)作性抓于,也就是耦合性做粤,使得模塊之間高度獨(dú)立,模塊間更多的從事著單向的調(diào)用工作捉撮。一個(gè)模塊需要某種服務(wù)就去找另一個(gè)模塊怕品,這使得程序呈現(xiàn)出層次性,高層通過(guò)接口調(diào)用底層巾遭,底層提供服務(wù)肉康。擯棄模塊間你中有我我中有你的曖昧關(guān)系闯估。
關(guān)鍵字:協(xié)作
但我們又需要模塊間的協(xié)作,所以需要回調(diào)(C++中是指針)吼和。如果A對(duì)象關(guān)心B對(duì)象的狀態(tài)變化涨薪,那么給B對(duì)象的狀態(tài)的變化注冊(cè)接口回調(diào)函數(shù),A實(shí)現(xiàn)接口炫乓,讓接口函數(shù)通知A刚夺,B對(duì)象狀態(tài)的改變,這樣在封裝了模塊變化的同時(shí)實(shí)現(xiàn)了模塊間的協(xié)作關(guān)系末捣,另辟獨(dú)徑的給對(duì)象解耦侠姑。
關(guān)鍵字:變量
回調(diào)函數(shù)跟普通函數(shù)只是在調(diào)用函數(shù)時(shí)略有區(qū)別。一般調(diào)用普通函數(shù)時(shí)箩做,直接寫函數(shù)名即可莽红。但是在調(diào)用所謂“回調(diào)”函數(shù)時(shí),是把它作為參數(shù)傳遞給另一函數(shù)邦邦。關(guān)鍵就在于“參數(shù)”這兩個(gè)字船老。為什么要把某個(gè)東西參數(shù)化?就是它存在變化的可能性圃酵。既然可以把變量做成參數(shù)柳畔,那么函數(shù)也同樣可以做成參數(shù),只要它們有變化的可能郭赐。對(duì)于一成不變的東西薪韩,顯然直接嵌入便可。