如何在Android活动之间共享socket.io连接?

3
在 socket.io Android 客户端 示例 项目中,我们读到了以下内容:

IO.socket() 返回一个带有默认选项的 http://chat.socket.io 的 socket。请注意,该方法会缓存结果,因此您可以从任何 Activity 或 Fragment 中始终获取同一 URL 的 Socket 实例。

因此,我决定测试一下,因为我的服务器上打开的套接字数量与客户端数量不相等。
我使用了以下服务器:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
    res.sendfile('index.html');
});

io.on('connection', function(socket){
    console.log('- connect event '+socket.id);
    socket.on('disconnect', function () {
        console.log('- disconnect event from id '+socket.id);
    });
});

http.listen(3000, '0.0.0.0', function(){
    console.log('. listening on *:3000');
});

我开发了一个非常简单的Android应用程序,包含两个活动,每个活动都会打开到相同服务器地址的socket.io连接,并允许轻松地在活动之间切换。

我启动服务器并启动应用程序,这是我得到的输出。

. listening on *:3000
( now I launch the app, opens Activity A )
- connect event 1FIizV3QMdGmnYUQAAAA
( I switch from Activity A to Activity B )
- connect event IzllGFxbpzI5NPNiAAAB
( I switch back from Activity B to Activity A )
- connect event pNt8Yvom5Rih_-01AAAC
- disconnect event from id 1FIizV3QMdGmnYUQAAAA
- disconnect event from id IzllGFxbpzI5NPNiAAAB

这个简单的测试表明,当活动内的onDestroy事件关闭回调时,套接字连接被销毁,当我恢复活动时,一个新的套接字连接被打开,但这与上面所述的因此,您始终可以从任何Activity或Fragment获得同一URL的Socket实例相矛盾,因为似乎正在创建新实例。
问题
似乎在Android开发中,多个活动模型非常常见(许多人建议仅反复更改片段效率低下),如何在这些活动之间有效地共享套接字连接,以便服务器可以拥有相同的套接字连接用于客户端,无论它包含多少个活动?
我考虑的选项是创建一个BoundService,该服务将处理套接字连接的所有回调和事件,并且所有活动都可以共享此服务,但是我没有找到与此类服务通信的有效方法。在这种情况下,IPC(进程间通信)可能会导致巨大的减速,特别是如果它基于Intents。
我希望能够获得一些有关使我的应用程序更专业并对他人有用的帮助。
1个回答

3
您可以使用 Service 来处理套接字,并使用 Binder 通过任意方法与服务通信,而不是通过 Intents。我假设您已经知道如何使用启动和/或绑定的服务,如果不知道,请查看指南
您需要重写 Service 的 onBind 回调函数,并返回一个自定义的 Binder 类的子类,该类公开了控制套接字、注册回调等 API。
下面是您的 Binder 代码示例:
private final IBinder socketBinder = new SocketBinder();

@Override
public IBinder onBind(Intent intent) {
    return socketBinder;
}

public class SocketBinder extends Binder {
    // Now you have access to all your Service's public methods
    public SocketService getService() {
        return SocketService.this;
    }
}

1
最终我已经完全测试了你的解决方案。从Activity中调用服务非常简单,另一种方式有点棘手,但是成功了!这个链接对我帮助很大。非常感谢! - Marek
嗨,我看到这个问题,我认为这很好。我也遇到了相同的错误,你能帮助我吗?可以分享一下解决方案的代码吗?谢谢。 - Dimoreno

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