java Android 监听器/回调 怎么做?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26006360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android listener / callback How to?
提问by Patricia
I have a pojo method that generates a Bitmap. When done, I want to throw the Bitmap to a UI Activity. This is a sample, but here it is:
我有一个生成位图的 pojo 方法。完成后,我想将位图扔给 UI 活动。这是一个示例,但这里是:
private void sendBitmap(Bitmap bitmap) {
// TODO - I'm in the pojo where I want to send the bitmap
}
FYI: The UI Activity that I want to notify is outside of my project. I mean, my project is an SDK, such that another developer would be grabbing this information as soon as it becomes available.
仅供参考:我想通知的 UI 活动在我的项目之外。我的意思是,我的项目是一个 SDK,这样其他开发人员就会在信息可用时立即获取该信息。
I've been trying to figure this out but getting somewhat confused.
我一直试图弄清楚这一点,但有点困惑。
- Do I need a "callback" interface?
- Or a "listener" interface?
- Or both?
- 我需要一个“回调”接口吗?
- 还是“侦听器”接口?
- 或两者?
I have created a Callback Interface in my MyActivity. So far, so good. This is what it looks like so far:
我在 MyActivity 中创建了一个回调接口。到现在为止还挺好。这是到目前为止的样子:
import android.graphics.Bitmap;
public class MyActivity {
// protected void whateverOtherMethods (Bundle savedInstanceState)
// {
// .
// .
// .
// .
// .
// .
//
// }
/**
* Callback interface used to supply a bitmap.
*/
public interface MyCallback {
public void onBitmapReady(Bitmap bitmap);
}
}
The demo application's DoSomethingActivity can implement the Callback Interface that I have created. This is the implementation of the callback in the demo application's DoSomethingActivity:
演示应用程序的 DoSomethingActivity 可以实现我创建的回调接口。这是演示应用程序的 DoSomethingActivity 中回调的实现:
private final MyCallback myCallback = new MyCallback() {
@Override
public void onBitmapReady(Bitmap bitmap) {
// TODO - do something with the bitmap
}
};
What is the step I'm missing to notify the callbacks? Maybe I almost have it, but I'm confused enough that I'm looking for a little help here.
我缺少通知回调的步骤是什么?也许我几乎拥有它,但我很困惑,所以我在这里寻求一些帮助。
UPDATE:
更新:
OK, I've added "implements" for my callback "BitmapCallback" interface into the pojo. Here it is:
好的,我已经为我的回调“BitmapCallback”接口添加了“实现”到 pojo 中。这里是:
public class ProcessImage implements BitmapCallback {
/**
* pojo method to return bitmap
*/
private void sendBitmap() {
this.onBitmapReady(bitmap);
}
@Override
public void onBitmapReady(Bitmap bitmap) {
// we still need to send the bitmap to cusomer App.
}
I cannot move the callback definition from the SDK Activity, because I want the customer's application to implement the callback in their code to handle the bitmap when it is returned to the customer's application.
我无法从 SDK 活动中移动回调定义,因为我希望客户的应用程序在其代码中实现回调,以便在位图返回到客户的应用程序时对其进行处理。
Here is the callback interface in my Activity:
这是我的 Activity 中的回调接口:
public interface BitmapCallback {
public void onBitmapReady(Bitmap processedBitmapy);
}
Here is the implementation in the customer's application:
这是客户应用程序中的实现:
private final BitmapCallback bitmapCallback = new BitmapCallback()
{
@Override
public void onBitmapReady(Bitmap bitmap) {
// TODO Auto-generated method stub
}
};
Call me dumb, but I'm having a hard time getting my head around this.
说我笨,但我很难理解这个问题。
回答by Ted Hopp
You're almost there. You just need to tell your POJO
about the callback instance. First, I would strongly recommend that you move the interface definition into the POJO
(since conceptually it has to do more with that object than with your activity) or make the interface an independent type. The POJO
should not know about types defined in the client class(es).
你快到了。您只需要告诉您POJO
有关回调实例的信息。首先,我强烈建议您将接口定义移入POJO
(因为从概念上讲,它必须对该对象执行更多操作,而不是对您的活动执行更多操作)或使接口成为独立类型。本POJO
不应该知道客户端类(ES)定义的类型。
Then you have a choice:
那么你有一个选择:
- use a listener pattern: in your
POJO
add a field to store an instance of the callback (or something more complicated if you want to support calling back to multiple listeners) and a method for setting the listener. Call the method from your activity (or wherever is appropriate) when you create or are setting up thePOJO
. - use a callback pattern: enhance the relevant API methods with a callback argument.
- 使用侦听器模式:在您
POJO
添加一个字段来存储回调的实例(或者更复杂的东西,如果您想支持回调多个侦听器)和设置侦听器的方法。创建或设置POJO
. - 使用回调模式:使用回调参数增强相关的 API 方法。
In either case, when the bitmap is ready you have the wiring to get the bitmap back to the activity.
在任何一种情况下,当位图准备好时,您都可以将位图返回到活动中。
EDIT
编辑
Here's an example of how this might be structured. You haven't provided any information about how you create your POJO
or invoke the processing, so I invented something just as an example. It assumes that the processing is taking place in a separate thread, which will call back to the activity when done. You can modify this as needed. (In particular, this can be much simpler if the POJO
is doing the work synchronously. Also, it would be better to use an AsyncTaskLoader
rather than a plain vanilla thread so that it interacts properly with the Activity
lifecycle.)
这是一个如何构建它的示例。您尚未提供有关如何创建POJO
或调用处理的任何信息,因此我发明了一些东西作为示例。它假定处理是在一个单独的线程中进行的,该线程将在完成后回调活动。您可以根据需要修改它。(特别是,如果POJO
同步完成工作,这会简单得多。此外,最好使用一个AsyncTaskLoader
而不是普通的普通线程,以便它与Activity
生命周期正确交互。)
BitmapCallback.java
位图回调函数
public interface BitmapCallback {
public void onBitmapReady(Bitmap processedBitmap);
}
MyActivity.java
我的活动.java
public class MyActivity extends Activity implements BitmapCallback {
Handler mHandler; // initialize this in onCreate
. . .
public void onRequestImage() {
ProcessImage processor = new ProcessImage();
getImage(this /* , other actual args */);
}
@Override
public void onBitmapReady(final Bitmap processedBitmap) {
// since this may be called from a non-UI thread, we can't update
// the UI directly.
mHandler.post(new Runnable() {
@Override
public void run() {
// handle the bitmap (update the UI, etc.)
}
});
}
}
ProcessImage.java
进程图像.java
public class ProcessImage {
public void getAnImage(final BitmapCallback callback /* , other formal args */) {
new Thread() {
@Override
public void run() {
Bitmap bitmap;
. . . // do the work
// then deliver the results
callback.onBitmapReady(bitmap);
}
}.start();
}
}
回答by santalu
Create an instance of your listener in your pojo class
在 pojo 类中创建侦听器的实例
MyCallback callback;
and set onBitmapReady inside sendBitmap method to notify activity
并在 sendBitmap 方法中设置 onBitmapReady 以通知活动
private void sendBitmap(Bitmap bitmap) {
// TODO - I'm in the pojo where I want to send the bitmap
callback.onBitmapReady();
}
回答by Patricia
It turned out that in order to make a callback work from inside an intent I needed to make the callback Serializable. After trying that and continuing to get an error reflecting that somehow the Activity was trying to serialize itself, which was causing the application to crash.
事实证明,为了使回调从意图内部工作,我需要使回调可序列化。在尝试之后并继续得到一个错误,反映 Activity 以某种方式试图序列化自己,这导致应用程序崩溃。
So I went back to the all wise one, Ted Hopp. Per Ted's advice, I ended up using Broadcasting. See the thread here: how to use LocalBroadcastManager?
所以我回到了最聪明的人,泰德霍普。根据 Ted 的建议,我最终使用了广播。请参阅此处的线程: 如何使用 LocalBroadcastManager?
Great advice, Ted, this solved my problem.
很好的建议,泰德,这解决了我的问题。
Lesson learned: If you are trying to use a callback from an SDK back to an "external" application and have problems, try looking at Broadcasting instead.
经验教训:如果您尝试使用从 SDK 返回到“外部”应用程序的回调并遇到问题,请尝试查看广播。