关闭

Java/Android中的函数调用&回调函数&自定义回调函数

228人阅读 评论(0) 收藏 举报

转载:http://blog.csdn.net/a_running_wolf/article/details/49359923


在做Android自定义控件时遇到要自定义回调函数的问题,想想自己还暂时没有那么精深的技术,赶紧返过头回来再重新研究Java中回调函数的问题。然而不幸的是,网上太多杂乱的帖子和博客都是转来转去,而且都是那一篇“C中的回调函数.....指针.....java....”,一点看不出来是自己的思路,估计都是哪哪哪抄来的!(呵呵,要么就是吐槽对了,要么就是我水平太烂读不懂还妄加评论可怜)还有一些很不错的文章,我会在最后参考中加上链接,大家可以看看。

        那么来开始我们的正题——什么是回调函数?

        我们一步步深入,先从函数调用开始:

        什么是函数(方法)调用?

        (别的什么语言的都忘了……呵呵,只看Java)Java中的函数调用无非就是(1)一个类中方法为了完成一个业务在执行过程中调用另一个方法,另一个方法也可以是自己,那就是递归啦;(2)不同类之间的函数调用,比如Class B(调用者Caller)中要调用Class A对象的一个方法(被调用者Callee)(不管A是作为B的成员,还是作为函数参数传进来)。方法调用是我们编程中必不可少的,可能我们平时视而不见罢了,否则一个工程的不同CLASS怎么协同工作呢?虽然简单,还是画个图说一下吧,待会对比一下可以更好的解释回调的机制:

        函数调用

        如上图Class B的函数method_B在执行过程中要调用成员a(Class A)的method_A1方法。

        我们刚开始学的时候都是这样做的。但是这样做存在问题,让我们来回顾一下我们当年学习的经过,不断将这个问题解释清楚:举个例子吧,不然嘴笨表达不清楚——A类是鸟类,B就是我们的工具类,现在我们要在工具类中完成这样的需求:通过工具类中的方法method_B完成不同鸟类飞的正确动作。

        第一阶段:显然就两个类完成不了这个需求!接着我们学习了继承,我们创建了“麻雀”、“大雁”、“鸵鸟”……各种“鸟”类子类,通过不同子类来完成不同的飞法,然后在工具类中创建不同子类的对象赋值给a,这样需求完成了。但是回头看看,我们创建了一大堆的子类,而且还用了隐式类型转换(子类赋值给父类),显然不够满意;

        第二阶段:后来,我们又学习了重载函数,在鸟类中创建一系列同名同名的“飞”函数,传入参数类型分别为麻雀、大雁……,这样我们就不用隐式转换了,直接调用鸟类对象a的飞方法,传入不同的大雁、麻雀……,a就能正确的飞了。这样需求也完成了,虽然避免了使用隐式转换,但是那些为数众多的子类可一个也没有落下。这样做显然也不符合我们的期望(我们的期望是什么?就是干最少的活,鸟就能正确的飞)。

        以上实现方式的问题就显而易见了:一方面我们要维护那些众多的子类,增加很大的工作量;另一方面,这样的编码缺乏灵活性,有多少种鸟你知道吗,每种鸟又是怎么飞的你知道吗,如果几种鸟极为相似,你是创建不同的类呢还是归为一类?所以有了下边这种实现方式,就是采用“回调函数”——

        什么是回调函数?

        直接上图吧:

        回调函数

        如上图,回调函数中必然用到接口。下边是感觉写得好的一段理解:

在Android的学习过程中经常会听到或者见到“回调”这个词,那么什么是回调呢?所谓的回调函数就是:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,这种机制就称为回调。

        我认为,上图中B类的方法method_B在调用a对象的method_A1时,method_A1执行到interface的抽象方法不知道怎么实现,正好B在调用他的时候提供了具体实现,所以method_A1返回来调用method_B提供的实现,这就是回调。其实,回调函数就是在一个不确定实现的方法METHOD中用interface或者它的抽象方法留个口子,留给具体调用者(调用前边那个不确定的方法METHOD)在调用时提供具体实现来补上那个口子。从而达到更灵活地编码的目的,也大大减少了子类的使用。就拿上边没完的例子继续吧——

        我们这样来实现:先定义一个接口,接口中声明抽象方法“飞”;在“鸟”类的“起飞”方法中把接口对象作为一个参数传进来,剩下的该怎么做就怎么做,遇到要飞的地方不知道具体怎么飞就调用接口提供的抽象方法“飞”;在工具类中调用“鸟”类的“起飞”方法时要实现了抽象方法的对象作为参数传入,然后你想让它怎么飞就怎么飞,具体实现是你调用的时候现写的。怎么样,这样的实现好吧?不用隐式转换,不用大量子类,调用的时候遇到什么鸟就怎么飞,达到了我们少干活的目的!

        什么是自定义回调函数?

        自定义回调函数,顾名思义,就是我们自己定义的回调函数。其实上边那个例子就是自定义回调函数!我们习惯上把别人定义好的回调函数叫作回调函数,Android系统中TextView、ImageView等和它们的子类控件的Onclick事件响应就是典型的回调机制。关于这个这位大虾讲得比我好——详细介绍Android中回调函数机制,详细看看会很有帮助的!


        一个简单的自定义回调函数的例子

        最后在举个简单的有代码的例子,看一下回调函数的运行过程:

        首先,我们定义一个interface:

[java] view plain copy
  1. public interface MyInterface {  
  2.     void sayYourName();  
  3. }  

        接着,我们定义一个类,其中一个方法以接口MyInterface类型的对象作为参数:

[java] view plain copy
  1. public class MyClass {  
  2.   
  3.     public MyClass() {  
  4.         Log.e("WangJ""MyClass-constructor");         //标注构造函数  
  5.     }  
  6.   
  7.     /* 用接口类型的对象作为输入参数 */  
  8.     public void sayYourName(MyInterface myInterface){  
  9.         Log.e("WangJ""MyClass-sayYourName_start");    //标注方法开始  
  10.         myInterface.sayYourName();                      //遇到不知道具体实现的时候就用接口的抽象方法  
  11.         Log.e("WangJ""MyClass-sayYourName_finish");   //方法结束  
  12.     }  
  13. }  

        最后,我们在Activity中调用这个类,创建对象并调用其方法,期间实现接口中抽象方法的具体实现逻辑,供回调使用:

[java] view plain copy
  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.   
  8.         MyClass myClass = new MyClass();  
  9.         myClass.sayYourName(new MyInterface() {                     //实现接口并作为参数传入  
  10.             @Override  
  11.             public void sayYourName() {  
  12.                 Log.e("WangJ""callBack-interface-implementor");    //具体操作实现  
  13.             }  
  14.         });  
  15.     }  
  16. }  

        好了,运行一下(我们这个例子没有任何界面,即默认Activity的界面,看日志):

        

        运行的顺序就是我们之前理解的:在B中调用A中的方法,A中方法在运行到接口中抽象方法时返回B中寻找具体实现(这就是回调),回调完成后继续执行下边未完成的步骤。


        好了,以上就是我所认识的回调函数,听起来高深,在你弄懂以后发现也没有太大的难度。但是想想Java研发者在设计这种机制的时候是多么有远见啊(好崇拜,虽然不知道他是谁)!文笔有限,理解不够,如有不足或错误,欢迎指正!最后如约附上那几篇不错的文章——


        参考文章:

        详细介绍Android中回调函数机制

        Android开发中Java回调机制的应用

        弄明白Android 接口回调机制


0
0
查看评论

自定义可以编辑内容的Dialog(回调函数)

public class Information_Dialog extends Dialog { private String fs_yisString; private OnDialogListener customDialogListener; EditText cont...
  • qq_22120329
  • qq_22120329
  • 2016-01-28 09:51
  • 636

Android实现自己的回调函数

Android实现自己的回调函数
  • u010670151
  • u010670151
  • 2016-04-12 16:03
  • 834

Java/Android中的函数调用&回调函数&自定义回调函数

在Android的学习过程中经常会听到或者见到“回调”这个词,那么什么是回调呢?所谓的回调函数就是:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,这种机制就称为...
  • a_running_wolf
  • a_running_wolf
  • 2015-10-23 12:47
  • 23123

JAVA同步回调函数

1.概述 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。          同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;     &...
  • libaolin198706231987
  • libaolin198706231987
  • 2016-01-06 11:29
  • 597

android之回调函数的用法和意义

CallBack是回调的意思,一般称之为回调函数 百科的解释:http://baike.baidu.com/link?url=8yMUwVEFRzxR4JGMxVN_UnFgJIH4WTnsybuW5NfwgKqVKP8NtShfJnNNeY9mBzRT 用一个比较形象的例子: 你饿了,想吃饭,就一...
  • jason0539
  • jason0539
  • 2013-08-22 08:54
  • 36321

Delphi中回调函数的使用

 我不善言表,只能用例子来说明,以下为一个例子:功能大体描述:Form1中有一个Edit和一个Button,当点击BUTTON时弹出FORM2,FORM2中也有一个EDIT和一个BUTTON,当点击FORM2中的BUTTON时,将FORM2中的EDIT的TEXT属性赋值给FORM1中的ED...
  • xiao_jun_0820
  • xiao_jun_0820
  • 2008-03-13 13:44
  • 1358

java 回调函数的写法

/** * 回调函数解析 * 1、要在这个类里面实例化另外一个类里面的接口,传递数据过去 * 2、在另外一个类里面调用他的接口的方法,实际执行的是这个类里面的回调方法 */ // 这是pass类中的一个回调函数————这是Activity类 pass.get...
  • mimi5821741
  • mimi5821741
  • 2015-09-17 16:50
  • 1115

自定义android用户控件,使用回调函数实现自定义事件

在android软件设计中会用到好多的控件,但系统自带的控件有好多不能够达到需要实现的功能或是控件不够美观。那怎么办呢? android应为我们提供了好多的控件,我们可以继承某一控件,然后对它进行重写来实现自己的一些功能。或是直接继承View自己定义自己的控件。 下面我来讲一下如...
  • gebitan505
  • gebitan505
  • 2014-01-14 15:21
  • 8463

android 通过回调实现 完全自定义Dialog 简单易用

最近的项目要用到弹出窗,然后在弹出窗上进行操作,选择啊什么的,于是就想到了dialog,查看了网上 很多例子,感觉有些太繁琐——定义theme然后在theme中定义dialog的样式,有些又达不到我想要的效果(监听位置什么的),感觉可以用但是琐碎,最后还是自己动手做一个吧,要优化的地方还很多,先看看...
  • u012895758
  • u012895758
  • 2013-12-20 11:21
  • 1300

深入理解Java回调函数

C语言中回调函数解释: 回调函数(Callback Function)是怎样一种函数呢? 函数是用来被调用的,我们调用函数的方法有两种: 1  直接调用:在函数A的函数体里通过书写函数B的函数名来调用之,使内存中对应函数B的代码得以执行。这里,A称为“主叫函数”(Caller),B称...
  • u010147215
  • u010147215
  • 2016-04-03 01:17
  • 5198
    个人资料
    • 访问:58636次
    • 积分:1214
    • 等级:
    • 排名:千里之外
    • 原创:54篇
    • 转载:69篇
    • 译文:0篇
    • 评论:10条
    最新评论