Android - 在SDK中实现回调

时间:2017-08-07 12:18:29

标签: java android callback sdk

我正在为Android设计SDK。 作为一名网络开发人员,我非常习惯并且习惯于回调,并且由于SDK会包含许多异步操作,因此我不确定最常见的是什么,最好的是什么?#34;在Android(或一般Java)上实现这种行为的方法。

我提出了几个选择:

1)监听器接口 - 将使用SDK的开发人员将实现一个包含所有回调的监听器接口,例如:

./liquibase generateChangeLog --diffTypes="data" 

作为一名网络开发人员,使用对我来说看起来有点太多的JS,"强迫"用户(开发人员)提前实现所有侦听器,当他甚至可能都不使用所有侦听器时。

2)单个听众设定者 基本上为每个异步方法设置一个监听器。例如:

interface ISDKListener {

    public void onA();
    public void onB();

}

class SDK {

    private ISDKListener _listener;    

    public SDK(ISDKListener listener) {
        _listener = listener
    }

    public void a() { 
        // Do stuff
        _listener.onA();
    }

    public void b() { 
        // Do stuff
        _listener.onB();
    }

}

3)与#2相同,但单独的成功和错误:

interface ISDKCallback {

    public void onComplete();

}

class SDK {

    private ISDKCallback _aCb;    
    private ISDKCallback _bCb;

    public void setAListener(ISDKCallback aCb) {
        _aCb = aCb
    }

    public void a() { 
        // Do stuff
        if (_aCb != null) _aCb.onComplete();
    }

    public void setBListener(ISDKCallback bCb) {
        _bCb = bCb
    }

    public void b() { 
        // Do stuff
        if (_bCb != null) _bCb.onComplete();
    }

}

4)结合#1和#3 - 一个包含所有回调的完整监听器,但每个回调将是2个回调,一个用于成功,一个用于错误:

interface ISDKCallback {

    public void onSuccess();
    public void onError(Exception e);

}

class SDK {

    private ISDKCallback _aCb;    

    public void setAListener(ISDKCallback aCb) {
        _aCb = aCb
    }

    public void a() { 
        try {
            // Do stuff
            if (_aCb != null) _aCb.onSuccess();
        } catch (Exception e) {
            if (_aCb != null) _aCb.onError(e);
        }
    }

}

第三个似乎最自然"自然"对我来说,由于成功和错误之间的分离(如JS上的promise interface ISDKListener { public void onA(); public void onAError(Exception e); public void onB(); public void onBError(Exception e); } class SDK { private ISDKListener _listener; public SDK(ISDKListener listener) { _listener = listener } public void a() { try { // Do stuff _listener.onA(); } catch (Exception e) { _listener.onAError(e); } } public void b() { try { // Do stuff _listener.onB(); } catch (Exception e) { _listener.onBError(e); } } } then)并分别设置每个回调。实际上,对我来说最自然的是在调用方法时传递回调,但就我搜索过的问题,我在Java的任何地方都没有找到这样的实现。

哪一个是最常见的,将是最自然的"大多数Android / Java开发人员?是否有其他建议在该平台上实现回调?

修改

为了澄清,回调要么是对HTTP请求的HTTP响应要么是BLE通信,例如方法catch会通过BLE向BLE外设发送一些请求,而a的回调将是在外围设备返回响应时调用(移动设备和外围设备正在通过BLE实现客户端 - 服务器协议)

2 个答案:

答案 0 :(得分:1)

我不是那里最大的专家,但如果你问的是最常见的实现,我会说数字1。你可以看看那里有很多库,我用了一个我自己很多,这是我发现最常用的解决方案。

一个很好的例子就是使用ExoPlayer(我之所以选择它只是因为我现在正在研究它)。

正如您所看到的,活动包括播放器的实例+所需的所有对象,例如BandwidthMeter并实现ExoPlayer.EventListener继承所有回调,例如onPlayerStateChanged

即便是Android API本身也会使用这种模式,也许太多了。但这是我猜的另一个话题。很多人发现这种方法有点令人困惑,因为你最终得到了一个回调地狱,我和他们在一起。

修改

另一个不同方法的好例子可以在Google API Client中找到(更适合您的情况)。

正如您所看到的,您使用两个侦听器连接到客户端,并且您有另一个可选的侦听器,用于处理具有不同接口和其他回调的错误。

<强>结论

我想最终它真的取决于你:解决方案1和2对我来说都很好看。 3号也可以使用,但我对它不太熟悉,也许这表明它不是Android开发中广泛使用的模式。

答案 1 :(得分:0)

通常,回调或侦听器接口是一种有效的方法,但我会选择Android LiveData。它是一个观察数据持有者,它包装您的数据并让其他人听取您的更改。在您的情况下,我会使用某种模型公开LiveData,然后您的sdk的用户将观察您的类型LiveData的返回值,以便将来更改数据。因此,你的sdk的用户不必实现任何东西。

我刚刚写了一篇博文,其中我回顾了回调(以及事件总线和LiveData),描述了我们应该使用一个而不是另一个的场景以及使用一个而不是一个的利弊其他。我认为它可能对您有用:

When and why to use LiveData