回调机制是一种很常见的设计模式,在Android中随处可见。因此我们可以站在Android开发者的角度来理解java中的回调机制。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { //do something } }); }
上面这段代码对于Anroid开发者来说再熟悉不过,找到Button对象并对按钮进行点击事件的监听。也许你已经知道这里用到了回调机制,但是你知道具体是怎么实现的吗?为了方便理解上面的示例,以下代码将尽可能简洁的模拟上面的操作。
//文件:OnClickListener.java,模拟android中的 View.OnClickListener package com.shelwee.listener; import com.shelwee.view.View; //Java中实现回调的基础,用接口实现回调。 public interface OnClickListener { //定义一个点击事件操作方法 void onClick(View v); }
//文件:View.java,模拟android中的 View对象 package com.shelwee.view; import com.shelwee.listener.OnClickListener; public class View { public void setOnClickListener(OnClickListener listener){ //模拟等待点击按钮操作 try { Thread. sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //此时的listener对象是从调用setOnClickListener方法的对象传进来的,即TestActivity.java中button传进来的new OnClickListener()匿名内部类对象 if ( listener != null) { //所以此时调用的onClick方法就是那个匿名内部类对象产生的,实际上就是调用TestActivity.java中Button实现OnClickListener接口的OnClick方法,因此会打印出“I was invoked”。 listener.onClick(this); } } }
//文件:Button.java,模拟android中的 Button,为View的子类 package com.shelwee.view; public class Button extends View{}
//文件:TestActivity.java,模拟一个Activity package com.shelwee.test; import com.shelwee.listener.OnClickListener; import com.shelwee.view.Button; import com.shelwee.view.View; public class TestActivity{ //模拟运行,三秒后控制台将打印“I was invoked” public static void main(String[] args) { TestActivity activity = new TestActivity(); activity.onCreate(); } public void onCreate(){ Button button = new Button();//模拟android上findViewById(); //button设置点击事件监听,并将OnClickListener匿名对象传到View.java中的setOnClickListener方法 button.setOnClickListener(new OnClickListener() { //View.java接收到OnClickListener对象后将回过来调用下面的OnClick方法 @Override public void onClick(View v) { // TODO Auto-generated method stub System.out.println("I was invoked"); } }); } }
总结:Java中的回调机制是通过接口来实现的,因此要使用回调机制这种设计模式:
首先要定义一个接口及其要实现的方法(如OnClickListener.java);
其次要被回调的地方必须实现上面的接口,或者采用匿名内部类实现(如TestActivity.java);
最后在另一个处理耗时或者等待操作的类中,接收传来的OnClickListener对象,然后调用回调方法(如View.java)。