今天重新看了一遍回調(diào),歸納如下:
簡(jiǎn)單來說就是A類中調(diào)用B類中的某個(gè)方法c,然后B類反過來調(diào)用A類中的方法d,這個(gè)方法d就是回調(diào)方法。
經(jīng)典的回調(diào)方式:
1.Class A實(shí)現(xiàn)接口Operate --前提1
2.Class A中包含一個(gè)Class B的引用b --前提2
3.Class B中有一個(gè)參數(shù)為operate的方法f(Operate operate) --前提3
4.A的對(duì)象a調(diào)用B的方法f(Operate operate) --A類調(diào)用B類的某個(gè)方法c
5.B的對(duì)象b可以在f(Operate operate)中調(diào)用A的方法 --B類調(diào)用A類的方法d
以下例子采用異步加回調(diào)
小王遇到一個(gè)問題需要問小李,但是小李在忙就跟小王說等辦完手頭的事再去幫他想答案,小王也不會(huì)傻傻地等就跟小李說他要出去,于是辦自己的事,后來過來一段時(shí)間小李找回小王告訴他答案。
首先實(shí)現(xiàn)一個(gè)回調(diào)接口:
public interface CallBack {
public void solve(String result);
}
然后是小王,實(shí)現(xiàn)了回調(diào)接口,相當(dāng)于前提一:
public class Wang implements CallBack {
//小李對(duì)象的引用,相當(dāng)于前提二
private Li li;
//小王的構(gòu)造方法,持有小李的引用
public Wang(Li li){
this.li = li;
}
//小王通過此方法去問小李
public void askQuestion(final String question){
//這里用一個(gè)線程就是異步,
new Thread(new Runnable() {
@Override
public void run() {
//小王調(diào)用小李的方法在這里注冊(cè)回調(diào)接口相當(dāng)于A類調(diào)用B類的方法C
li.executeMessage(Wang.this, question);
}
}).start();
play();
}
//小王出去了
public void play(){
System.out.println("我要逛街去了");
}
//小李知道答案后通過此方法告訴小王,這就是小王的回調(diào)方法
@Override
public void solve(String result) {
System.out.println("小李告訴小王的答案是--->" + result);
}
}
最后是小李:
public class Li {
//相當(dāng)于前提三--B類有參數(shù)為Operate operate的方法f()
public void executeMessage(CallBack callBack, String question){
System.out.println("小王問的問題--->" + question);
//模擬小李辦自己的事情需要很長時(shí)間
for(int i=0; i<10000;i++){
}
//小李的回答
String result = "答案是2";
//相當(dāng)于B類反過來調(diào)用A的方法D
callBack.solve(result);
}
}
測(cè)試類:
public class Test {
public static void main(String[]args){
Li li = new Li();
Wang wang = new Wang(li);
wang.askQuestion("1 + 1 = ?");
}
}
再來說說同步回調(diào):
Android View中的onClick()是一個(gè)回調(diào)方法:
這是view的一個(gè)回調(diào)接口
public interface OnClickListener {
void onClick(View v);
}
//相當(dāng)于前提一---Class A實(shí)現(xiàn)了接口
public class MainActivity extends Activity implements OnClickListener{
//相當(dāng)于前提二--Class A 包含Class B的引用
private Button button;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button1);
//Class A調(diào)用View的方法,而Button繼承于View--A類調(diào)用B類的方法c
button.setOnClickListener(this);
}
//回調(diào)函數(shù)
@Override
public void onClick(View v) {
Toast.makeText(getApplication(), "OnClick", Toast.LENGTH_LONG).show();
}
}
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
protected OnClickListener mOnClickListener; //前提三--Class B中包含一個(gè)參數(shù)為OnClickListener類型的函數(shù) public void setOnClickListener(OnClickListener l) { if (!isClickable()) { setClickable(true); } mOnClickListener = l; } public boolean performClick() { sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); if (mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); //B類調(diào)用A類的某個(gè)方法d,就是回調(diào)方法 mOnClickListener.onClick(this); return true; } return false; } }