【问题标题】:How to share socket.io connection between Android activities?如何在 Android 活动之间共享 socket.io 连接?
【发布时间】:2016-02-14 23:04:48
【问题描述】:

在 socket.io Android 客户端 example 项目中,我们读到:

IO.socket() 使用默认选项返回http://chat.socket.io 的套接字。请注意,该方法会缓存结果,因此您始终可以从任何 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 活动内的事件我关闭回调时,套接字连接被破坏,当我恢复活动时,一个新的套接字连接被打开,但它与上述so you can always get a same Socket instance for an url from any Activity or Fragment 相矛盾,因为它似乎正在创建该新实例。

问题

看来,多activity模型在Android开发中很常见(很多人认为只是一遍又一遍地改变Fragment效率低下),如何高效地在这些activity之间共享一个socket连接,让服务器可以拥有相同的客户端的套接字连接,无论它包含多少活动?

我考虑的选项是创建一个BoundService,它将处理套接字连接的所有回调和事件,并且所有活动都可以共享此服务,但是我没有找到与此类服务通信的有效方法。在这种情况下,IPC(进程间通信)可能会大大降低速度,特别是如果它基于 Intents。

我希望我能在使我的应用更专业方面获得一些帮助,并且它也对其他人有用。

【问题讨论】:

    标签: android node.js android-activity socket.io connection-pooling


    【解决方案1】:

    您可以使用Service 处理套接字并使用Binder 通过任意方法而不是通过Intents 与服务通信。我假设您已经知道如何使用已启动和/或绑定的服务,如果不知道 - read the guide

    您需要重写 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;
        }
    }
    

    【讨论】:

    • 我终于完成了对您的解决方案的测试。从 Activity 调用服务非常简单,另一种方式有点棘手但有效! this 帮了我很多忙。非常感谢!
    • 嗨,我看到了这个问题,我认为这很好,我遇到了同样的错误,你能帮我吗,分享一下关于这个解决方案的代码。请问候
    猜你喜欢
    • 1970-01-01
    • 2011-07-13
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2012-10-07
    相关资源
    最近更新 更多