android中的回调

小鱼儿 2022-08-07 03:57 355阅读 0赞



回调这种思想大家应该都用过,只是很多人不知道那是回调的一种罢了,前几天整理了一下自己对于回调的理解,就顺便把自己的一些想法整理到博客中。

让我们从一个小故事开始。

某天,我打电话向你请教问题,当然是个难题,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了 XX 分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。

OK,这个故事我们先告一段落,其实,这就是一个典型的回调过程。

1343818308_1915.png

C不会自己调用b,C提供b的目的就是让S来调用它,而且C不得不提供。S并不知道C提供的b是什么,因此S会约定b的接口规范(函数原型),然后由C提前通过S的一个函数r告诉S自己将要使用b函数(即注册)。r为注册函数。

简单来说:

回调函数就是预留给系统调用的函数,而且我们往往知道该函数被调用的时机

好的,那我们继续完善下上面的那幅图。

1343818361_9158.png

看着这幅图,其实我们回想一下,会发现,生活中到处都有回调这种思想存在。软件的很多思想其实只是我们实际生活中思维方式的一种转化。

再将一个小故事:

我们平时考试答题的第一件事是干嘛?没错,是写上学号和姓名。这里注意了,我们填写学号和姓名不是给自己看的 ( 即该方法不是给自己调用的 ) ,而是给老师登记分数时看的 ( 预留给系统将来调用 ) ,这其实就是一个回调的应用。老师提供接口 ( 输入姓名,学号规则 ) ,我们利用接口注册。

看到上面的小故事,大家对回调就有了一些了解了,我们再回到开头的那个小故事。

那个故事说明了“异步 + 回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。

好的,我们已经大概知道了回调的基本流程,下面,来看看Android中回调的基本使用。

场景一:

[java] view plain copy print ?

  1. Button button = (Button)this.findViewById(R.id.button);
  2. button.setOnClickListener(newButton.OnClickListener() {
  3. //回调函数
  4. @override
  5. publicvoidonClick(View v) {
  6. buttonTextView.setText(“按钮被点击了”);
  7. }
  8. });

    Button button = (Button)this.findViewById(R.id.button);
    button.setOnClickListener(newButton.OnClickListener() {

    //回调函数
    @override
    publicvoidonClick(View v) {
    buttonTextView.setText(“按钮被点击了”);
    }
    });

上面的代码给按钮加了一个事件监听器,这其实就是 “ 回调 ” 最常见的应用场景之一。我们自己不会显式地去调用 onClick 方法。用户触发了该按钮的点击事件后,它会由 Android 系统来自动调用。

熟悉的组件,熟悉的监听器。。。

场景二:

[java] view plain copy print ?

  1. @Override
  2. publicvoidonCreate(BundlesaveInstanceState) {
  3. super.onCreate(saveInstanceState);
  4. // You code…
  5. }
  6. @Override
  7. publicvoidonResume() {
  8. super.onResume();
  9. // You code…
  10. }

    @Override
    publicvoidonCreate(BundlesaveInstanceState) {
    super.onCreate(saveInstanceState);
    // You code…
    }
    @Override
    publicvoidonResume() {
    super.onResume();
    // You code…
    }

Activity的整个生命周期基本上都说回调函数在发挥作用。

好了,看了两个我们经常使用的回调方式,我们先来总结下 android 利用回调的基本方法。其实,只是把我们的那张图翻译了下。

首先,服务器端创建一个回调接口

[java] view plain copy print ?

  1. //声明一个接口
  2. public interface ICallBack {
  3. void postExec();
  4. }
  5. //另外一个类有方法里面有个参数是这个接口类型的对象
  6. public class FooBar {
  7. private ICallBackcallBack;
  8. public void setCallBack(ICallBackcallBack) {
  9. this.callBack =callBack;
  10. }
  11. public void doSth() {
  12. callBack.postExec();
  13. }
  14. }
  15. //实现回调
  16. public class Test {
  17. public static void main(String[] args) {
  18. FooBarfoo = newFooBar();
  19. foo.setCallBack(newICallBack() {
  20. public void postExec() {
  21. System.out.println(“method executed.”);
  22. }
  23. });
  24. foo.doSth();//调用函数
  25. }
  26. }

    //声明一个接口
    public interface ICallBack {

    1. void postExec();

    }
    //另外一个类有方法里面有个参数是这个接口类型的对象
    public class FooBar {

    1. private ICallBackcallBack;
    2. public void setCallBack(ICallBackcallBack) {
    3. this.callBack =callBack;
    4. }
    5. public void doSth() {
    6. callBack.postExec();
    7. }

    }
    //实现回调
    public class Test {

    1. public static void main(String[] args) {
    2. FooBarfoo = newFooBar();
    3. foo.setCallBack(newICallBack() {
    4. public void postExec() {
    5. System.out.println("method executed.");
    6. }
    7. });
    8. foo.doSth();//调用函数
    9. }

    }

对回调的深入思考:

程序的本质就是代码跳转,不管同步异步反射接口虚函数,本质上都是函数调用。函数我们要调用它,就需要它的指针,不同语言通过不同的方式来得到这个指针。而我们定义的接口其实就是一个函数指针,那么那个注册过程,其实就是相当于对那个函数指针赋值。通过这个函数指针来调用我们定义的自实现函数。利用函数指针实现回调,在RIL的C代码中无处不在,大家可有空研习。

发表评论

表情:
评论列表 (有 0 条评论,355人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Android 函数揭秘

    在学习Android的过程中,经常会遇到”回调函数”这个词,那么甚么是回调函数呢? 简单地说,回调函数就是通过其指针来调用的函数, 她不会被自己所在的对象调用, 只会在调用别人

    相关 android

         回调这种思想大家应该都用过,只是很多人不知道那是回调的一种罢了,前几天整理了一下自己对于回调的理解,就顺便把自己的一些想法整理到博客中。   让我们从一个