如何在 Android 中定义回调?

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

在此图中,在返回路径上有对其他方法的各种不同回调。

google io presentation slide

如何声明这些方法是什么

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

我觉得我对设计模式有了一个基本的了解,但是在如何处理返回路径方面,我总是被绊倒。

256124 次浏览

在许多情况下,您有一个接口并传递一个实现它的对象。例如,对话框具有 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的语法,现在还早。

如果可以使用现有接口: android.os.Handler.Callback,则不需要定义新接口。传递 Callback 类型的对象,并调用回调的 handleMessage(Message msg)

当我看到有什么事情发生时,我会发出一个我的活动正在监听的事件:

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

    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");
}
});

如果你想知道更多关于片段之间通信(回调)的信息,请点击这里: Http://developer.android.com/guide/components/fragments.html#communicatingwithactivity

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

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

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);

编辑: 刚刚意识到有一个更好的方法可以得到相同的结果(减去对何时执行回调的精确控制) :

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

示例使用接口实现回调方法。

定义接口 新界面 java

包 javaapplication1;

public interface NewInterface {
void callback();
}

创建一个新类 NewClass.java,它将调用主类中的回调方法。

package javaapplication1;


public class NewClass {


private NewInterface mainClass;


public NewClass(NewInterface mClass){
mainClass = mClass;
}


public void calledFromMain(){
//Do somthing...


//call back main
mainClass.callback();
}
}

实现接口 NewInterface-callback ()方法的主类 JavaApplication1.java。它将创建并调用 NewClass 对象。然后,NewClass 对象将依次回调它的 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来实现这个目的

创建一个广播接收器:

   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);

暂停中取消接收器:

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

假设主要功能是触发事件的活动:

fun main() {


val worker = Worker()


worker.setOnCallListener(
object: OnCallListener {
override fun onCall() {
// here we define what should happen
// when the event accures
print("event happend")
}
}
)


// most events will be called from Android system itself
// but in our case we have to call it manually
worker.listener.onCall()
}

Worker类有一个类型 OnCallListener接口的实例 以及设置其价值的方法:

class Worker() {
lateinit var listener: OnCallListener


fun setOnCallListener(listener: OnCallListener) {
this.listener = listener
}
}

OnCallListener接口如下:

interface OnCallListener {
fun onCall()
}