如何分享Android活动之间的socket.io连接?

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

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

所以我决定testing一下,因为我的服务器上打开的套接字数量不等于客户端的数量。

我用下面的服务器:

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 

这个简单的testing表明,当活动内部的onDestroy事件closurescallback时,套接字连接被销毁,当我恢复活动一个新的套接字连接打开,但它相矛盾, so you can always get a same Socket instance for an url from any Activity or Fragment上面的so you can always get a same Socket instance for an url from any Activity or Fragment ,因为它似乎正在创build新的实例。

在Android开发中,似乎多重活动模型是非常普遍的(许多人认为一次又一次地改变片段效率不高),如何在这些活动之间高效地共享一个套接字连接,以便服务器可以拥有相同的套接字连接客户不pipe它包含多less活动?

我考虑过的选项是创build一个BoundService来处理socket连接的所有callback和事件,所有Activity都可以共享这个服务,但是我没有find与这样的服务进行通信的有效方法。 IPC(进程间通信)在这种情况下可能是一个巨大的减速,尤其是如果它是基于意图。

我希望我可以帮助我的应用程序更亲,也会对其他人有用。

您可以使用Service来处理套接字,并使用Binder通过任意方法而不是通过Intents与服务进行通信。 我假设你已经知道如何使用开始和/或绑定的服务,如果没有 – 阅读指南 。

你需要重写Service的onBindcallbackonBind并返回一个Binder类的自定义子类,它公开了一个API来控制套接字,注册callback等。

以下是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; } }