首页
登录 | 注册

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

接口回调,咋听起来可能会感觉很高大上,很复杂的逻辑的一种思想。特别是在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接口回调到此结束。



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.008 s.
京ICP备10005923号