Java中的回调函数
声明:本文主要转载别人的文章,并对文章中不太清楚的地方加了一些自己的理解。
一、回调函数的解释
回调只是个概念,就是把你的接口对应的实现类的一个实例对象,当成一个参数传递给一个函数调用,那个函数处理过程中会调用你的这个接口中的方法。
---网友
Java中的回调机制是通过接口来实现的,因此要使用回调机制这种设计模式:首先要定义一个接口及其要实现的方法,其次要被回调的地方必须实现上面的接口,或者采用匿名内部类实现,最后在另一个处理耗时或者等待操作的类中,接收传来的对象,然后调用回调方法。
---网友
回调方法是把功能定义和功能实现分离的一种手段,是一种松耦合的设计思想。
---网友
二、案例说明【原文地址忘了复制,实在抱歉,以后找到补上】
回调方法的接口:1
1. public interface ICallBack {
2. // 回调方法
3. public void callBackMethod();
4. }
回调方法的实现类(监听类):2
1. //监听类:实现回调方法所在的接口
2. public class CallBackListener implements ICallBack {
3. @Override //重写接口的callBackMethod方法
4. public void callBackMethod() {
5. System.out.println("回调");
6. }
7. }
回调方法的调用类:3
1. //调用类
2. public class Caller {
3. private ICallBack callBack; //接口引用
4. public void setCallBack(ICallBack callBack){
5. this.callBack = callBack; //给接口引用赋值
6. }
7. //调用方法:调用监听类中重写接口的回调方法
8. public void call(){
9. this.callBack.callBackMethod();
10. }
11. }
业务处理类:
1. //业务处理类
2. public class Main {
3. public static void main(String[] args) {
4. //创建调用类对象
5. Caller caller = new Caller();
6. //给调用类的成员赋值
7. caller.setCallBack(new CallBackListener());
8. // 在业务处理的时候调用【在调用类中间接的调用监听类中的方法】
9. caller.call();
10. }
11. }
程序图示说明【自己的理解】
熟悉Android中Button点击事件处理的同学应该都知道跟上面是一样的。
ICallBack------->OnClickListener接口
CallBackListener--------->实现OnClickListener接口的类
Caller-------->Button对象
Main-------->业务处理类(Activity)
三、引用文章
所谓回调:就是A类【前提:A必须实现一个带回调方法的接口】中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法,
如下图所示【个人理解】
图示解释说明:
Class A实现接口CallBack callback——背景1
class A中包含一个class B的引用b ——背景2
class B有一个参数为callback的方法f(CallBack callback) ——背景3
A的对象a调用B的方法 f(CallBack callback) ——A类调用B类的某个方法 C
然后b就可以在f(CallBack callback)方法中调用A的方法 ——B类调用A类的某个方法D
大家都喜欢用打电话的例子,好吧,为了跟上时代,我也用这个例子好了,我这个例子采用异步加回调
有一天小王遇到一个很难的问题,问题是“1 + 1 = ?”,就打电话问小李,小李一下子也不知道,就跟小王说,等我办完手上的事情,就去想想答案,小王也不会傻傻的拿着电话去等小李的答案吧,于是小王就对小李说,我还要去逛街,你知道了答案就打我电话告诉我,于是挂了电话,自己办自己的事情,过了一个小时,小李打了小王的电话,告诉他答案是2
1. //这是一个回调接口
2. public interface CallBack {
3. /**
4. * 这个是小李知道答案时要调用的函数告诉小王,也就是回调函数
5. * @param result 是答案
6. */
7. public void solve(String result);
8. }
1. /**
2. * 这个是小王
3. * @author xiaanming
4. * 实现了一个回调接口CallBack,相当于----->背景一
5. */
6. public class Wang implements CallBack {
7. /**
8. * 小李对象的引用
9. * 相当于----->背景二
10. */
11. private Li li;
12. /**
13. * 小王的构造方法,持有小李的引用
14. * @param li
15. */
16. public Wang(Li li){
17. this.li = li;
18. }
19. /**
20. * 小王通过这个方法去问小李的问题
21. * @param question 就是小王要问的问题,1 + 1 = ?
22. */
23. public void askQuestion(final String question){
24. //这里用一个线程就是异步,
25. new Thread(new Runnable() {
26. @Override
27. public void run() {
28. /**
29. * 小王调用小李中的方法,在这里注册回调接口
30. * 这就相当于A类调用B的方法C
31. */
32. li.executeMessage(Wang.this, question);
33. }
34. }).start();
36. //小网问完问题挂掉电话就去干其他的事情了,诳街去了
37. play();
38. }
40. public void play(){
41. System.out.println("我要逛街去了");
42. }
43. /**
44. * 小李知道答案后调用此方法告诉小王,就是所谓的小王的回调方法
45. */
46. @Override
47. public void solve(String result) {
48. System.out.println("小李告诉小王的答案是--->" + result);
49. }
50. }
1. //这个就是小李啦
2. public class Li {
3. /**
4. * 相当于B类有参数为CallBack callBack的f()---->背景三
5. * @param callBack
6. * @param question 小王问的问题
7. */
8. public void executeMessage(CallBack callBack, String question){
9. System.out.println("小王问的问题--->" + question);
10. //模拟小李办自己的事情需要很长时间
11. for(int i=0; i<10000;i++){
12. //null
13. }
14. /**
15. * 小李办完自己的事情之后想到了答案是2
16. */
17. String result = "答案是2";
18. /**
19. * 于是就打电话告诉小王,调用小王中的方法
20. * 这就相当于B类反过来调用A的方法D
21. */
22. callBack.solve(result);
23. }
24. }
1. //测试类
2. public class Test {
3. public static void main(String[]args){
4. /**
5. * new 一个小李
6. */
7. Li li = new Li();
8. /**
9. * new 一个小王
10. */
11. Wang wang = new Wang(li);
12. /**
13. * 小王问小李问题
14. */
15. wang.askQuestion("1 + 1 = ?");
16. }
17. }
通过上面的那个例子你是不是差不多明白了回调机制呢,上面是一个异步回调,我们看看同步回调吧,onClick()方法
现在来分析分析下Android View的点击方法onclick();我们知道onclick()是一个回调方法,当用户点击View就执行这个方法,我们用Button来举例好了
1. //这个是View的一个回调接口
2. /**
3. * Interface definition for a callback to be invoked when a view is clicked.
4. */
5. public interface OnClickListener {
6. /**
7. * Called when a view has been clicked.
8. * @param v The view that was clicked.
9. */
10. void onClick(View v);
11. }
8. /**
9. * 这个就相当于Class A
10. * @author xiaanming
11. * 实现了 OnClickListener接口---->背景一
12. */
13. public class MainActivity extends Activity implements OnClickListener{
14. /**
15. * Class A 包含Class B的引用----->背景二
16. */
17. private Button button;
18. @Override
19. public void onCreate(Bundle savedInstanceState) {
20. super.onCreate(savedInstanceState);
21. setContentView(R.layout.activity_main);
22. button = (Button)findViewById(R.id.button1);
23. /**
24. * Class A 调用View的方法,而Button extends View----->
25. A类调用B类的某个方法 C
26. */
27. button.setOnClickListener(this);
28. }
29.
30. /**
31. * 用户点击Button时调用的回调函数,你可以做你要做的事
32. * 这里我做的是用Toast提示OnClick
33. */
34. @Override
35. public void onClick(View v) {
36. Toast.makeText(getApplication(), "OnClick", Toast.LENGTH_LONG).show();
37. }
38. }
下面是View类的setOnClickListener方法,就相当于B类咯,只把关键代码贴出来
1. /**
2. * 这个View就相当于B类
3. * @author xiaanming
4. */
5. public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
6. /**
7. * Listener used to dispatch click events.
8. * This field should be made private, so it is hidden from the SDK.
9. * {@hide}
10. */
11. protected OnClickListener mOnClickListener;
12. /**
13. * setOnClickListener()的参数是OnClickListener接口------>背景三
14. * Register a callback to be invoked when this view is clicked. If this view is not
15. * clickable, it becomes clickable.
16. * @param l The callback that will run
17. * @see #setClickable(boolean)
18. */
19. public void setOnClickListener(OnClickListener l) {
20. if (!isClickable()) {
21. setClickable(true);
22. }
23. mOnClickListener = l;
24. }
25. /**
26. * Call this view's OnClickListener, if it is defined.
27. * @return True there was an assigned OnClickListener that was called,
28. false
29. * otherwise is returned.
30. */
31. public boolean performClick() {
32. sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
33. if (mOnClickListener != null) {
34. playSoundEffect(SoundEffectConstants.CLICK);
35. //这个不就是相当于B类调用A类的某个方法D,这个D就是所谓的回调方法咯
36. mOnClickListener.onClick(this);
37. return true;
38. }
39. return false;
40. }
41. }
这个例子就是Android典型的回调机制,看完这个你是不是更进一步的理解了回调机制呢? 线程run()也是一个回调方法,当执行Thread的start()方法就会回调这个run()方法,还有处理消息都比较经典等等