在android中实现Socket.io的最佳方法

我计划在这个库中为基于聊天的应用程序在android中实现Socket.io。 据我所知,图书馆看起来很不错。 我想知道如何在整个应用程序中始终保持单个套接字连接? 在这里,我列出了实现的方法,其中我需要最好和最稳定的方式。

三种方式

MainApplication类扩展了Application

通过这种方式,我们有一个很好的范围,即在主线程 (或应用程序的生命周期)中维护套接字连接,并且每当从活动中需要套接字实例时我们都可以轻松获得它。 但它的主要线程也是问题所在。 它可能会阻止主线程。

BoundService

通过这种方式,我们可以服务与活动绑定 ,我们可以简单地使用它。 在单独的线程中执行是实现IO /网络调用的方法。 但是,交叉处理转移比在同一过程中直接访问更昂贵。

独生子

在Singleton中维护连接也很有意义。 但是我们不知道实例何时被进程杀死,因为它在活动生命周期中不起作用。

如果我有意义,请帮助我。 如果没有评论出来。

编辑

我已经给出了更适合我的答案。

首先,应用程序的onCreate()与您的用例无关,因为在非服务代码中首次启动时,您无法在后台运行线程。

另外,我建议使用Google Cloud Messaging而不是创建自己的机制。 最好是设备的电池寿命和更少的代码供您处理。

如果您确实希望完全自己实现该聊天,那么Service是您唯一的选择。 您也可以将它与单例组合,但我不建议这种方法。 您可以使用广播和BroadcastReceiver在您的ServiceActivity之间进行通信,我认为它比绑定服务更容易,因为绑定到服务是异步的,并且与简单广播相比它会造成很多混乱。

维护socket连接的服务

根据Ofek Ron提到的Service with BroadcaseReceiverBoundService 更好 。 因为它是一个保持沟通的繁琐过程。 而且我也推荐pub/sub广播方式,比如OttoEventBus (我自己建议Otto by Square,这是干净而精彩的api)。

奥托的优点
1.清洁Api
2.您可以在任何ActivityFragmentService类中订阅和发布。
3. 解耦 。 (您必须在代码中尽可能少地耦合)。

还有一点是在onStartCommand()使用START_STICKY在销毁之后启动服务。 请参阅此参考。

MainApplication启动服务

最好的做法是在扩展ApplicationMainApplication中启动该服务。 因为当存在内存约束或用户强行从堆栈中关闭应用程序时,应用程序将被终止。 因此, onStartCommand()不会被频繁调用,就像我们在Activity中实现一样。

实现在线状态

您可以通过在MainApplication类中实现Application.LifeCycleCallbacks来实现在线状态,该类具有活动的大部分生命周期回调,并将在回调中得到通知。 这样您就可以在没有任何锅炉板代码的情况下实现Online状态。 (如果有人需要帮助,请告诉我)。

上传或下载图像或文件。

最佳实践是由IntentService实现,因为它在一个单独的线程中运行。 我保证哪个会提供最佳性能,因为它由android本身处理,而不是像我们创建的线程。

你可以结合第一种方式和第三种方式:

Application创建Socket并将它们声明为static 。 因此,您可以在应用程序的每个位置维护和访问它们。 不要忘记创建单独的Thread来执行网络操作,可以使用ThreadPool来管理那些Thread 。 如果要从这些Thread更新UI,可以使用HandlerMessage与UI Thread进行通信

在创建自己的socket.io客户端实现之前,您应该给这个库一个机会: https : //github.com/socketio/socket.io-client-java

我在我的一个项目中使用它与node.js服务器进行通信,该服务器工作得非常好。 实际上,你的所有建议都是正确的,主要取决于你想要达到的目标。 但是,一个上下文始终可用:应用程序上下文。 因此,您应该在Application类中保留一个单例实例,并通过getApplicationContext()获取它。

用户的在线状态:在这里,您应该创建一个后台服务,该服务正在不断地监听用户状态。 由于信息不多,这应该没问题,不应该耗费太多电池。 此外,如果有可用的新信息,您可以发送一个标志,只有在有新内容的情况下,您才会启动另一个接收新数据的线程。 这样可以保持较低的数据。

聊天:只有在应用处于活动状态时才会传输聊天数据。 所以,这应该在一个活动中完成。

服务和活动都可以从应用程序上下文访问socket.io客户端的单例实例。 只要你不处理主线程上的任何复杂数据,一切都很好。 因此,将您的调用包装到单独的线程中,并仅在实际需要时启动它们。