如何在Android中定义callback?

在最近的Google IO中,有一个关于实现宁静的客户端应用程序的演示。 不幸的是,这只是一个高层次的讨论,没有实现的源代码。

在这个图表中,在返回path上有对其他方法的各种不同的callback。

谷歌io演示文稿幻灯片

我如何声明这些方法是什么?

我理解callback的概念 – 一段在特定事件发生后被调用的代码,但我不知道如何实现它。 到目前为止,我实现callback的唯一方法是重写各种方法(例如onActivityResult)。

我觉得我对devise模式有一个基本的了解,但是我仍然不知如何处理返回path。

在很多情况下,你有一个接口并传递一个实现它的对象。 对话框例如有OnClickListener。

就像一个随机的例子:

// The callback interface interface MyCallback { void callbackCall(); } // The class that takes the callback class Worker { MyCallback callback; void onEvent() { callback.callbackCall(); } } // Option 1: class Callback implements MyCallback { void callbackCall() { // callback code goes here } } worker.callback = new Callback(); // Option 2: worker.callback = new MyCallback() { void callbackCall() { // callback code goes here } }; 

我可能搞砸了选项2中的语法。现在还早。

当我看来有什么事发生时,我就开始了一个我的活动正在监听的事件:

//在(自定义)视图中声明

  private OnScoreSavedListener onScoreSavedListener; public interface OnScoreSavedListener { public void onScoreSaved(); } // ALLOWS YOU TO SET LISTENER && INVOKE THE OVERIDING METHOD // FROM WITHIN ACTIVITY public void setOnScoreSavedListener(OnScoreSavedListener listener) { onScoreSavedListener = listener; } 

//在活动中声明

  MyCustomView slider = (MyCustomView) view.findViewById(R.id.slider) slider.setOnScoreSavedListener(new OnScoreSavedListener() { @Override public void onScoreSaved() { Log.v("","EVENT FIRED"); } }); 

如果你想知道更多关于片段之间的通信(callback),请看这里: http : //developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

当您可以使用现有的接口时,无需定义新的接口: android.os.Handler.Callback 。 传递一个Callbacktypes的对象,并调用callback的handleMessage(Message msg)

澄清龙的答案(因为我花了一段时间才弄清楚如何处理Handler.Callback ):

Handler可以用来通过传递Message来执行当前或另一个线程中的callback函数。 该Message保存要从callback中使用的数据。 Handler.Callback可以传递给Handler的构造函数,以避免直接扩展Handler。 因此,通过当前线程的callback执行一些代码:

 Message message = new Message(); <set data to be passed to callback - eg message.obj, message.arg1 etc - here> Callback callback = new Callback() { public boolean handleMessage(Message msg) { <code to be executed during callback> } }; Handler handler = new Handler(callback); handler.sendMessage(message); 

编辑:刚才意识到有一个更好的方法来获得相同的结果(减去确切的时候执行callback的控制):

 post(new Runnable() { @Override public void run() { <code to be executed during callback> } }); 

使用接口实现callback方法的示例

定义接口NewInterface.java

包javaapplication1;

 public interface NewInterface { void callback(); } 

创build一个新类NewClass.java 。 它将调用主类中的callback方法。

 package javaapplication1; public class NewClass { private NewInterface mainClass; public NewClass(NewInterface mClass){ mainClass = mClass; } public void calledFromMain(){ //Do somthing... //call back main mainClass.callback(); } } 

主类JavaApplication1.java,实现了NewInterface – callback()方法的接口。 它将创build并调用NewClass对象。 然后,NewClass对象将依次callback它的callback()方法。

 package javaapplication1; public class JavaApplication1 implements NewInterface{ NewClass newClass; public static void main(String[] args) { System.out.println("test..."); JavaApplication1 myApplication = new JavaApplication1(); myApplication.doSomething(); } private void doSomething(){ newClass = new NewClass(this); newClass.calledFromMain(); } @Override public void callback() { System.out.println("callback"); } } 

您也可以使用LocalBroadcast来达到此目的。 这是一个快速的问题

创build一个广播接收器:

  LocalBroadcastManager.getInstance(this).registerReceiver( mMessageReceiver, new IntentFilter("speedExceeded")); private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Double currentSpeed = intent.getDoubleExtra("currentSpeed", 20); Double currentLatitude = intent.getDoubleExtra("latitude", 0); Double currentLongitude = intent.getDoubleExtra("longitude", 0); // ... react to local broadcast message } 

这是如何触发它

 Intent intent = new Intent("speedExceeded"); intent.putExtra("currentSpeed", currentSpeed); intent.putExtra("latitude", latitude); intent.putExtra("longitude", longitude); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 

在onPause中unRegister接收器:

 protected void onPause() { super.onPause(); LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); }