深入浅出的理解接口回调

Posted by Jays on April 25, 2015

1.什么是接口回调?

接口回调是指:可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被实际实现的接口中的方法时,就是通知相信的对象调用接口的方法,这一过程成为对象功能的接口回调。

把上面的话翻译过来可以这样理解:

  • Class A实现接口CallBack callback —–背景一
  • Class A中包含一个Class B的应用b —–背景二
  • Class B中有一个参数为callback的方法f(CallBack callback)—背景三
  • A的对象a调用B的方法f(CallBack callback)—–A类调用B类的某个方法C
  • 然后b就可以在f(CallBack callback)方法中调用A的方法—–B类调用A方法D

2.实际例子

上面的描述还是稍显空洞,用一个实际例子来解释一下。有一天小王打电话问小李一个问题,小李一下子也不知道,就告诉小王说等我忙完手上的事情就去想想答案。小王在小李的过程中就出去逛街玩儿去了。过了一段时间,小李打了小王的电话,告诉他了答案。

    //这是一个回调接口    
    public interface CallbackListener {
	  void solve(String result);
    }

小王

    //小王实现了接口,相当于A
    public class Wang implements CallbackListener {  
	private Li li;

    //持有B类小李的引用
	public Wang(Li li) {
		this.li = li;
	}
    
    //小王通过此方法向小李问问题
	public void askQuestion(final String question) {
		new Thread(new Runnable() {
			public void run() {
                 //调用小李的executeMessage方法
                 //相当于A类调用B类的方法C
				li.executeMessage(Wang.this, question);
			}
		}).start();
     //问完问题做自己的事情
		play();
	}

	public void play() {
		System.out.println("我要去逛街了");
	}
  
      //小李知道答案后调用A类的方法,即回调方法
	public void solve(String result) {
		System.out.println("小李告诉小王的答案是--->" + result);
	   }

    }

小李

    public class Li {
	
	public void executeMessage(CallbackListener callbackListener,String question){
		System.out.println("小王的問題是-->"+question);
         /*
          *模拟小李需要很长时间
          */
		for(int i=0;i<1000;i++){
			
		}
		String result="2";
         //打电话告诉小王,即回调方法
		callbackListener.solve(result);
    	}
    }

测试类:

    public class Test {
	 public static void main(String[] args) {
		Li li = new Li();
		Wang wang=new Wang(li);

		wang.askQuestion("1+1=?");
	  }

    }

上面就是就是一个异步接口回调的例子。接下来看一个同步回调的例子。当我们为Button设置监听事件的的时候就用到了接口回调。 OnClickListener:


     public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        void onClick(View v);
    }

MainActivity中实现了接口OnClickListener且包含了B类的引用(Button是View的子类)


    public class MainActivity extends BaseActivity implements OnClickListener {
	
    Button bt_click;
    bt_click.setOnClickListener(this);
    //...
      
	@Override
    public void onClick(View v) {
	}

B类中

    public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
    ...
      /**
     * Register a callback to be invoked when this view is clicked. If this view is not
     * clickable, it becomes clickable.
     *
     * @param l The callback that will run
     *
     * @see #setClickable(boolean)
     */
    public void setOnClickListener(OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }   

当需要执行一些耗时操作时,A类让B类去执行,结束后再返回给A,这就是接口回调使用的情景。

以上就是对接口回调的一点理解。