Android 关于接口回调原理的解析

来源:互联网 发布:重要财经数据 编辑:程序博客网 时间:2024/04/28 13:44

接口回调,咋听起来可能会感觉很高大上,很复杂的逻辑的一种思想。特别是在Android中,每次都用,但有时候只是知道这样用,却不知道怎么实现的。但其实任何面向对象语言使用无非就是封装,继承,多态。其他的万变不离其中。要理解接口回调的机制,我觉得首先要清楚面向对象多态的概念。以下是自己在开发中的理解。
多态:c++中的理解时允许将子类类型的指针赋值给父类类型的指针,其实就是有一个容器保存了父类的指针类型,然后子类对象创建出来后放入容器内,然后该对象就实现了子类的方法(其实该思想更容易理解接口回调)。
下面用一个例子看看Java中的多态

public  class Person {    public  void speak()    {        System.out.println("人类说人话");    }}public class Chinese extends Person{    public void speak() {           System.out.println("中国人说汉语");    }}

定义两个类,父类Person,子类分别为Chinese。首先父类Person p1=new Person();Person p2=new Chinese(); 然后我们分别调用p1.speak(),和p2.speak();得到的结果分别是“人类说人话”,“中国人说汉语”。这里父类Person 的引用p2用子类Chinese实例化,而用子类实例化之后,其调用的就是子类中的方法。这里用的其实就是Java中的多态思想。
遥控器例子:现在我手里有个遥控器(其实就是父类的引用)有2个按键控制父类频道1(广东卫视),频道2(深圳卫视)(2个按键调用类中2个方法,对应固定的方法名),控制父类的电视机(用父类实例化)调用的就是父类的方法,如果控制子类的电视(用子类实例化),控制的还是频道1和频道2,可是此时调用的就是子类的方法了(频道1可能就是ccav5了),这时候遥控器中的2个按键可以正常使用,但是电视机播放的内容可能不一样(子类重写了父类的方法)。相反子类的引用用父类实例化就会报错(子类的方法多,遥控器按钮多,父类寒碜就2个频道,满足不了子类当然报错)。
明白了电视机的例子,android接口回调就明白了。
首先我们来看看android的经典setOnClickListener,这是一个典型的接口回调。
android系统中源码:

      public void setOnClickListener(OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }        getListenerInfo().mOnClickListener = l;    }
   public interface OnClickListener {        /**         * Called when a view has been clicked.         *         * @param v The view that was clicked.         */        void onClick(View v);    }
      public boolean performClick() {        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);        ListenerInfo li = mListenerInfo;        if (li != null && li.mOnClickListener != null) {            playSoundEffect(SoundEffectConstants.CLICK);            li.mOnClickListener.onClick(this);            return true;        }        return false;    }

android中的setOnClickListener 的接口回调主要就是上面三个方法。首先有一个接口OnClickListener 里面有一个方法void onClick(View v)。然后setOnClickListener(OnClickListener l)里面传入的是一个接口对象,之后performClick()方法判断接口对象不为空的时候就执行li.mOnClickListener.onClick(this)方法。此时因为接受的OnClickListener 对象是用子类来实例化的。所以调用的onClick方法就是我们自己写的onClick的方法了。
举例

createButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {              Toast.makeText(MainActivity.this, "ethan", Toast.LENGTH_LONG).show();            }        });    }

这里是用匿名内部类实例化了OnClickListener接口,匿名内部类只是没有名字,其实也是一个子类实现了OnClickListener接口,这里的new OnClickListener()其实就是实现接口类的对象。因此在setOnClickListener方法里面执行的时候,最终会执行到listener.onClick方法(listener是OnClickListener接口的引用)由于接口引用是用子类来实现的,引用多态的概念和上面遥控器的例子,我们知道程序调用的是子类中的onClick方法,也就是我们平时所写的onClick方面里面的内容。
Android接口回调到此结束。

3 1