Android监听器/回调如何?

Posted

技术标签:

【中文标题】Android监听器/回调如何?【英文标题】:Android listener / callback How to? 【发布时间】:2014-11-18 07:47:24 【问题描述】:

我有一个生成位图的 pojo 方法。完成后,我想将位图扔到 UI 活动中。这是一个示例,但这里是:

private void sendBitmap(Bitmap bitmap) 
    // TODO - I'm in the pojo where I want to send the bitmap

仅供参考:我要通知的 UI 活动在我的项目之外。我的意思是,我的项目是一个 SDK,因此其他开发人员会在它可用时立即获取此信息。


我一直试图弄清楚这一点,但有些困惑。

    我需要一个“回调”接口吗? 还是“监听器”接口? 或两者兼而有之?

我在 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”接口的“实现”添加到 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.


我无法从 SDK Activity 中移动回调定义,因为我希望客户的应用程序在其代码中实现回调,以便在位图返回给客户的应用程序时对其进行处理。

这是我的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,您可以在其中调用自定义侦听器。 developer.android.com/reference/android/view/… 为什么投反对票?这是基于正在更改的某些位图的回调。它与 UI 无关。 【参考方案1】:

你快到了。你只需要告诉你的POJO 回调实例。首先,我强烈建议您将接口定义移到POJO 中(因为从概念上讲,它与该对象的作用比与您的活动更多)或使接口成为独立类型。 POJO 不应该知道客户端类中定义的类型。

那么你有一个选择:

    使用侦听器模式:在您的POJO 中添加一个字段来存储回调实例(或者如果您想支持回调多个侦听器,则可以使用更复杂的东西)和设置侦听器的方法。当您创建或设置POJO 时,从您的活动(或任何适当的地方)调用该方法。 使用回调模式:使用回调参数增强相关 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();
    

【讨论】:

首先,我要感谢您提供的信息。我仍在为此苦苦挣扎。请参阅上面问题末尾添加的我的 UPDATE @Lucy - 你的逻辑倒退了。应该实现回调功能的是活动,而不是 pojo。该功能的定义不应与活动的定义相关联;否则 pojo 将依赖于活动,这是不可取的。我添加了一个具体的例子来说明我的意思。【参考方案2】:

在你的 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();

【讨论】:

没那么容易。实例为空,您无法实例化接口。当我终于明白这一点时,我会感到比现在还要愚蠢。感谢您的帮助。【参考方案3】:

事实证明,为了使回调从意图内部工作,我需要使回调可序列化。在尝试之后并继续得到一个错误,反映 Activity 试图以某种方式序列化自身,这导致应用程序崩溃。

所以我回到了全智者 Ted Hopp。根据 Ted 的建议,我最终使用了广播。在此处查看主题:how to use LocalBroadcastManager?

很好的建议,泰德,这解决了我的问题。

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

【讨论】:

以上是关于Android监听器/回调如何?的主要内容,如果未能解决你的问题,请参考以下文章

android单例中的监听如何回调

Android 基于回调的事件处理机制详解

Android事件处理

Android - 查看子项数量更改时的侦听器/回调

Android dialog实现监听生命周期

Android app后台回到前台时的监听