Android 的回调事件详解

看见网上一些回调的解释都很复杂的,特别基于Android的自定义回调,感觉一头雾水,于是乎,我也写了这篇基于我对回调的解释。

先来看一个简单的例子:
有两个类 ClassA ,和 ClassB, ClassA调用ClassB里面的方法,

public class ClassB {

  public void method_from_classB(){

    for(int i=0;i<10;i++)
      System.out.print("..."+i);
  }
}
public class ClassA {

  public static void main(String args[]){

    ClassB classB = new ClassB();

    classB.method_from_classB();
  }
}

输出:

...0...1...2...3...4...5...6...7...8...9

卧槽,哪个傻逼写的博文,侮辱我的智商不是吗,嘻嘻,是为了做比较,接下来看看利用回调, ClassA 是怎么调用 ClassB中的 方法的,注意是回调:

让ClassB 实现 ClassA定义的接口

public class ClassB implements ClassA.ClassAInterface{

  public ClassB(){

    new ClassA().RegisterInterface(this);
    System.out.println("...ClassB..."+this);
  }

  @Override
  public void method_from_interface() {

    for(int i=0;i<10;i++)
      System.out.print("..."+i);
  }

  /*  public void method_from_classB(){

  for(int i=0;i<10;i++)
    System.out.print("..."+i);
  }*/
}

ClassA里面定义接口和抽象方法:

public class ClassA {

  public static ClassAInterface classAInterface;

  public interface ClassAInterface{

    public void method_from_interface();
  }
  public void RegisterInterface(ClassAInterface a_interface){

    this.classAInterface = a_interface;
    System.out.println("...a_interface..."+a_interface);
  }

  public static void main(String args[]){

    ClassB classB = new ClassB();// 标记@1,最后面做解释
    //classB.method_from_classB();
    System.out.println("...classAInterface..."+classAInterface);
     if(classAInterface != null){
        classAInterface.method_from_interface();
      }
  }
}

输出:

...0...1...2...3...4...5...6...7...8...9

整理下,也就是 我在ClassA里面定义了一个接口(interface),接口里面又定义了一个方法,但没有方法体,也就不做任何事情。

当 ClassA 执行到 mian() 函数时,就会调用接口的方法,但前面讲了,接口的方法没有实现具体的事情,它就会找到 ClassB 里面对应的 方法,来实现具体的事情。

呦呦呦,ClassA 的接口的方法是怎么找到 ClassB 的方法,难道会上天???

也就是下面分析这句代码是怎么上天的:

// 利用接口的回调实现 ClassB中 的方法的 具体事情

 classAInterface.method_from_interface();

我在上面的代码中用 System.out.println 打印出了日志做分析:

第一个(ClassA中的方法):

  public void RegisterInterface(ClassAInterface a_interface){

    this.classAInterface = a_interface;
    System.out.println("...a_interface..."+a_interface);
  }

输出:

...a_interface...ClassB@3ddb8962

第二个:

public ClassB(){

    new ClassA().RegisterInterface(this);
    System.out.println("...ClassB..."+this);
  }

输出:

...ClassB...ClassB@3ddb8962

第三个:

System.out.println("...classAInterface..."+classAInterface);
     if(classAInterface != null){
        classAInterface.method_from_interface();
      }

输出:

...classAInterface...ClassB@3ddb8962

看到这里是不是恍然大悟呢 ,输出都是 “ ClassB@3ddb8962 ” 也就是ClassB 对象的引用!!!

啊!接口只不过是将 ClassB 对象的引用 传到 ClassA中而已,那这句会上天的语句是不是很好解释了呢。

classAInterface.method_from_interface();

相当于  ClassB@3ddb8962.method_from_interface();

这是不是跟最上面到的代码:

    ClassB classB = new ClassB();
    classB.method_from_classB();

一样呢,这也是为什么我最开始要举这个例子的原因!!!

相信看到这里应该理解了接口的回调是怎么回事了吧。
但有一点又糊涂了,为什么 要接口回调这么麻烦的,最上面的在ClassA里面执行:

    ClassB classB = new ClassB();
    classB.method_from_classB();

不是照样可以 ClassA 调用 ClassB 里面的 方法。。。。但要是ClassA 要调用ClassC,ClassD ...,里面的方法呢,是不是还要改变ClassA里面的代码,实例化ClassC,ClassD ... 的对象,显然是不好的,要是使用接口那就不用改变ClassA 里面的代码了,任何类只要实现ClassA 里面的接口就可以.

解释一下 标记@1 :

上面那段话好像跟 标记@1 违背了,在 ClassA 里面确实也需要实例化 ClassB对象。

因为要 【利用】 初始化的时候执行构造方法里面的代码:

public ClassB(){
    // 相当于回调事件的注册,初学者出现回调空指针很有可能这边忘记‘注册'了
    new ClassA().RegisterInterface(this);
  }

将this 传递给 ClassA ,作用也就是 上面利用 日志分析的作用。

但再 Android 开发中救你不必这样了,
可以在 Activity 的初始化时执行:

@Override
  protected void onCreate(Bundle savedInstanceState) {

     // 相当于回调事件的注册,初学者出现回调空指针很有可能这边忘记‘注册'了
    new ClassA().RegisterInterface(this);
}

在Android 开发中 ClassA 里面的 mian() 函数可以用事件来代替,触发:
如:

button.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        // TODO 自动生成的方法存根
        if(classAInterface != null){
        classAInterface.method_from_interface();
      }
    });
(0)

相关推荐

  • 基于Android中Webview使用自定义的javascript进行回调的问题详解

    先说为什么需要讨论这个问题. 现在很多的手机应用,都可能会直接嵌入一个web页面.这样做的好处:一个是功能更新方便,维护起来容易,只需要维护服务器的页面即可,不需要更新客户端:另一个是功能通用,不仅android可以用,ios也可以用,symbian也可以直接用. 那为什么现在很多手机应用并不做成web方式的呢?原因很多.一个是现阶段web方式展现能力相对较弱,如果对于应用的美观程度要求比较高,就无法使用web方式:一个是web方式速度相对较慢,用户体验会受一些影响:一个是现阶段流量还是相对宝贵

  • Android中Fragment多层嵌套时onActivityResult无法正确回调问题的解决方法

    前言: Fragment也可以使用startActivityForResult方法去打开一个Activity,然后在其onActivityResult方法中处理结果,可是当Fragment嵌套的时候,由于FragmentActivity的BUG导致只会回调最外那层Fragment的onActivityResult方法,于是乎当前Fragment就收不到结果了. BUG分析: 解决这个问题之前我们先通过源码分析一下是什么原因导致的,以22.2.1版本的support-v4库为例 我们先从Fragm

  • Android的Fragment的生命周期各状态和回调函数使用

    回调函数 就像activities一样,fragments也有它们自己的生命周期.理解fragments的生命周期,可以使你在它们被销毁的时候保存它们的实例,这样在它们重新被创建的时候,就能恢复它们之前的状态. 流程: onAttach() 作用:fragment已经关联到activity, 这个是 回调函数 @Override public void onAttach(Activity activity) { super.onAttach(activity); Log.i("onAttach_

  • Android中回调接口的使用介绍

    MainActivity如下: 复制代码 代码如下: package cn.testcallback; import android.os.Bundle; import android.widget.Toast; import android.app.Activity; /** * Demo描述: * Android中回调接口的使用 */ public class MainActivity extends Activity { @Override protected void onCreate(

  • Android 回调详解及简单实例

    Android  回调 前言: Android中的回调最经典的就是点击事件设置监听(一般通过switch(v.getId()))这里写个最基本的 btn_rigister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // TODO log in } }); view对外暴露了一个接口onClick public interface OnClickListene

  • 深入浅析Android接口回调机制

    在使用接口回调的时候发现了一个经常犯的错误,就是回调函数里面的实现有可能是用多线程或者是异步任务去做的,这就会导致我们期望函数回调完毕去返回一个主函数的结果,实际发现是行不通的,因为如果回调是多线程的话你是无法和主函数同步的,也就是返回的数据是错误的,这是非常隐秘的一个错误.那有什么好的方法去实现数据的线性传递呢?先介绍下回调机制原理. 回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数

  • Android异步回调中的UI同步性问题分析

    Android程序编码过程中,回调无处不在.从最常见的Activity生命周期回调开始,到BroadcastReceiver.Service以及Sqlite等.Activity.BroadcastReceiver和Service这些基本组件的回调路径和过程也就是通常意义上所谓的"生命周期".同时,在处理具体的业务逻辑时,常常设计到不同线程之间的通信,如下载图片完成后通知 UI线程更新UI,凡此类场景,无论使用哪一种具体的线程间通信方式(Handler/Message.Handler/p

  • 理解Android中Activity的方法回调

    为什么需要方法回调? 方法回调是功能定义和功能分离的一种手段,是一种松耦合的设计思想.在JAVA中回调是通过接口来实现的.作为一种系统架构,必须要有自己的运行环境,并且要提供用户的实现接口. 下面通过实例来模拟一下Android中Activity的方法回调思想. Activity接口 复制代码 代码如下: package com.xujing.test  //定义接口  public interface Activity{      //创建时调用的方法      public void onC

  • android自定义控件和自定义回调函数步骤示例

    自定义控件的步骤: 1 View的工作原理2 编写View类3 为View类增加属性4 绘制屏幕5 响应用户消息6 自定义回调函数 java代码 复制代码 代码如下: private class MyText extends LinearLayout {    private TextView text1; /*     * private String text;     *      * public String getText() { return text; }     *     

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

    提示:在阅读本文章之前,请确保您对Touch事件的分发机制有一定的了解 在Android的学习过程中经常会听到或者见到"回调"这个词,那么什么是回调呢?所谓的回调函数就是:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,这种机制就称为回调. 下面我们拿具体的Button的点击事件进行模拟分析: 首先,在View类中我们能找到setOnClickLis

随机推荐