java接口回調(diào)機(jī)制想必大家并不陌生,其思想簡單洼冻,應(yīng)用廣泛崭歧,如網(wǎng)絡(luò)請求、界面的點(diǎn)擊監(jiān)聽等碘赖,是一個(gè)java開發(fā)者必須要掌握的基本思想之一驾荣。那么我們一起來簡單地了解一下java的接口回調(diào),并且掌握其思想和理解其意義普泡。
我們在做java開發(fā)時(shí)經(jīng)常會遇到文件下載播掷、請求服務(wù)器數(shù)據(jù)等基本操作,大家都知道網(wǎng)絡(luò)請求屬于耗時(shí)操作撼班,我們?nèi)绻谥苯又骶€程執(zhí)行這些邏輯時(shí)很可能會造成主線程堵塞歧匈,從而導(dǎo)致程序崩潰。我們通常都是開啟一個(gè)子線程來執(zhí)行網(wǎng)絡(luò)請求操作砰嘁。
public void doSomeWork() {
new Thread(new Runnable() {
@Override
public void run() {
// 執(zhí)行邏輯件炉,發(fā)起網(wǎng)絡(luò)請求,如請求后臺數(shù)據(jù),下載文件等
}
}).start();
}
上面這段代碼想必你已經(jīng)再熟悉不過了矮湘,不過當(dāng)我們在做一次開發(fā)時(shí)斟冕,經(jīng)常會多次使用網(wǎng)絡(luò)請求,比如多次請求服務(wù)器的數(shù)據(jù)缅阳,所以我們更愿意將其寫成一個(gè)小框架:
public String doRequest(String url) {
new Thread(new Runnable() {
@Override
public void run() {
// 執(zhí)行邏輯磕蛇,請求后臺json數(shù)據(jù)
}
}).start();
//將獲取的數(shù)據(jù)轉(zhuǎn)化為String,并返回
}
那么問題來了:
我們在寫成框架時(shí)十办,網(wǎng)絡(luò)請求是在子線程中進(jìn)行的秀撇,很可能數(shù)據(jù)還沒返回來的時(shí)候,doRequest方法就已經(jīng)執(zhí)行完了(不懂的就需要去看看守護(hù)線程哦)向族,那么這時(shí)候返回的數(shù)據(jù)就沒有任何意義了呵燕,最終的結(jié)果是我們得到的String為空的,而不是我們期待的的數(shù)據(jù)件相。
解決此問題的一種方法:
子線程請求到數(shù)據(jù)后再扭,直接對數(shù)據(jù)進(jìn)行處理(缺陷:失去了框架的意義)
public void doRequestAndDealData(String url) {
new Thread(new Runnable() {
@Override
public void run() {
// 執(zhí)行邏輯,請求后臺json數(shù)據(jù)
// 直接對獲取到的數(shù)據(jù)進(jìn)行處理
}
}).start();
}
對比上一段代碼适肠,我們這里直接對返回的數(shù)據(jù)進(jìn)行了處理映企,而沒有在方法里返回?cái)?shù)據(jù)计呈,但是這樣的處理邏輯就是唯一的了,并不能隨著請求的url不同而執(zhí)行不同的處理邏輯,那么有沒有一種方法能將在子線程中獲取到的數(shù)據(jù)"傳出去"灶挟,使其能得到成功的處理呢? 這就是接口回調(diào)的巧妙之處了季稳!
①先定義一個(gè)接口:
public abstract class CallBackListener {
public abstract void onFinish()
public abstract void onError(Exception ex);
}
②在類A中通過在子線程發(fā)起網(wǎng)絡(luò)請求
并將接口作為參數(shù)馋嗜,寫到類A中!
public class A {
public void doRequest(String url,CallBackListener backListener) {
new Thread(new Runnable() {
@Override
public void run() {
try {
// 執(zhí)行邏輯辩稽,發(fā)起網(wǎng)絡(luò)請求,如請求后臺數(shù)據(jù)惧笛,下載文件等
backListener.onFinish();
} catch (Exception ex) {
backListener.onError(ex);
}
}
}).start();
}
}
③在類B中調(diào)用類A的對象,發(fā)起請求逞泄,并且對請求得到的數(shù)據(jù)進(jìn)行處理患整。
public class B {
public void deal() {
A a = new A();
a.doRequest("http://請求的url",new CallBackListener() {
@Override
public void onFinish() {
//請求成功的邏輯拜效,如下載完成后的處理,請求到數(shù)據(jù)后的處理
}
@Override
public void onError(Exception ex) {
// 異常邏輯
}
});
}
}
我們在B中調(diào)用A的方法時(shí)各谚,重寫了接口中的方法紧憾,當(dāng)發(fā)起的網(wǎng)絡(luò)請求完成時(shí),就會調(diào)用我們重寫后的方法昌渤,這就是接口回調(diào)赴穗,這樣根據(jù)需要來進(jìn)行不同的重寫,同樣保留了框架的意義膀息。
我們在下載完成后般眉,界面的點(diǎn)擊事件監(jiān)聽,后臺數(shù)據(jù)請求完成時(shí)...還有很多地方都可以用到接口回調(diào)潜支,掌握其思想后甸赃,我們也可以寫的更加規(guī)范一點(diǎn)了,如將A類中的接口作參數(shù)就寫為單的一個(gè)方法冗酿,setListener(CallBackListener listener);大家自己去實(shí)踐吧辑奈。