安卓监听器/回调函数怎么做?

3
我有一个POJO方法可以生成位图。完成后,我想将位图传递给UI活动。这是一个示例,如下所示:
private void sendBitmap(Bitmap bitmap) {
    // TODO - I'm in the pojo where I want to send the bitmap
}

注意:我想要通知的UI Activity在我的项目之外。我的项目是一个SDK,因此另一个开发人员会在信息可用时立即获取这些信息。


我一直在尝试弄清楚这个问题,但有点困惑。

  1. 我需要一个“回调”接口吗?
  2. 还是一个“监听器”接口?
  3. 还是两者都需要?

我已经在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);
    }
}

演示应用的DoSomethingActivity可以实现我创建的回调接口。以下是演示应用的DoSomethingActivity中回调的具体实现:

private final MyCallback myCallback = new MyCallback() {

    @Override
    public void onBitmapReady(Bitmap bitmap) {
        // TODO - do something with the bitmap
    }
};

我缺少哪一步来通知回调函数?也许我已经接近成功了,但我很困惑,所以在这里寻求一点帮助。
更新: 好的,我已经为我的回调“BitmapCallback”接口添加了"implements"。这是它:
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.

}

我无法将SDK活动中的回调定义移动,因为我希望客户应用程序在其代码中实现回调以处理位图,当位图返回到客户应用程序时。下面是我的 Activity 中的回调接口:
public interface BitmapCallback {

    public void onBitmapReady(Bitmap processedBitmapy);
}

以下是客户应用程序中的实现:

private final BitmapCallback bitmapCallback = new BitmapCallback()  
{

    @Override
    public void onBitmapReady(Bitmap bitmap) {
        // TODO Auto-generated method stub          
    }
};

别笑我蠢,但我对此感到有些困惑。


你要回调哪个事件?如果是点击事件,你应该查看OnClickListener,在那里你可以调用你的自定义监听器。http://developer.android.com/reference/android/view/View.OnClickListener.html - Peshal
为什么会有负评?这是基于某些位图更改的回调。它与UI无关。 - Patricia
3个回答

7
你已经快成功了,只需要告诉你的POJO(普通Java对象)关于回调实例的信息。首先,我强烈建议将接口定义移到POJO中(因为这个概念上更与该对象相关),或将接口作为一个独立类型。POJO不应知道在客户类中定义的类型。
然后你有两种选择:
1. 使用监听器模式:在你的POJO中添加一个字段来存储回调实例(如果要支持向多个监听器回调,则可以使用更复杂的方式),并添加一个设置监听器的方法。当你创建或设置POJO时从你的活动(或其他合适的地方)调用该方法。
2. 使用回调模式:增强相关的API方法以包含回调参数。
无论哪种情况,当位图准备好时,你都可以将其传回到活动中。
这是一个可能的结构示例。你没有提供有关如何创建POJO或调用处理的任何信息,因此我只是举了一个例子。它假定处理正在单独的线程中进行,完成后将回调到活动。您可以根据需要修改此内容。(特别是如果POJO同步执行工作,则可以简单得多。另外,最好使用AsyncTaskLoader而不是普通的线程,以便它与Activity生命周期正确交互。)

BitmapCallback.java

public interface BitmapCallback {
    public void onBitmapReady(Bitmap processedBitmap);
}

MyActivity.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

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

首先,我想感谢您提供的信息。我仍在努力解决这个问题。请查看我在问题末尾添加的更新 - Patricia
@Lucy - 你的逻辑是反过来的。应该是活动而不是pojo实现回调功能。该功能的定义不应与活动的定义绑定;否则,pojo将依赖于活动,这是不可取的。我添加了一个具体的示例,以说明我的意思。 - Ted Hopp

1
在你的POJO类中创建你的监听器的一个实例。
MyCallback callback;

在sendBitmap方法中设置onBitmapReady,以通知活动。
private void sendBitmap(Bitmap bitmap) {
    // TODO - I'm in the pojo where I want to send the bitmap
    callback.onBitmapReady();
}

这并不容易。该实例为空,您无法实例化一个接口。当我最终理解这一点时,我会感到比现在更愚蠢。谢谢你的帮助。 - Patricia

0

结果证明,为了使一个回调函数在意图内部起作用,我需要将回调函数序列化。尝试后,仍然出现错误,反映Activity正在尝试对自身进行序列化,导致应用程序崩溃。

所以我回到了聪明的Ted Hopp那里。根据Ted的建议,最终我使用了广播。请参见此处的线程:如何使用LocalBroadcastManager?

太好了,Ted,这解决了我的问题。

教训:如果您尝试从SDK使用回调函数返回到“外部”应用程序并遇到问题,请尝试查看广播。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接