15

我正在构建一个 android 应用程序,只要该应用程序正在运行,它就会定期与服务器通信。

我通过在应用程序启动时启动与服务器的连接来做到这一点,然后我有一个单独thread的用于接收名为的消息ReceiverThread,它thread从 中读取消息socket,对其进行分析,并将其转发到应用程序的适当部分。

thread在一个循环中运行,读取它必须读取的任何内容,然后阻塞read()命令直到新数据到达,所以它大部分时间都被阻塞了。

我通过另一个线程处理发送消息,称为SenderThread. 我想知道的是:我应该SenderThread以类似的方式构建吗?意思是我应该为这个线程维护某种形式的队列,让它发送队列中的所有消息然后阻塞直到新消息进入队列,或者我应该在每次需要发送消息时启动一个新的线程实例,让它发送消息然后“死”?我倾向于第一种方法,但我不知道在性能(将阻塞线程保留在内存中与初始化新线程)和代码正确性方面实际上更好。

此外,由于我的所有活动都需要能够发送和接收消息,因此我在Application课堂上持有对两个线程的引用,这是一种可接受的方法还是我应该以不同的方式实现它?

我遇到的一个问题是,有时如果我关闭我的应用程序并再次运行它,我实际上有两个 ReceiverThread 实例,所以我收到了两次消息。

我猜这是因为我的应用程序实际上并没有关闭并且前一个线程仍然处于活动状态(在read()操作中被阻塞),当我再次打开应用程序时,一个新线程被初始化,但两者都连接到服务器所以服务器将消息发送给双方。有关如何解决此问题或如何完全重新组织它以使其正确的任何提示?

我尝试查找这些问题,但在我的第一个问题中发现了一些相互矛盾的示例,并且没有任何有用且适用于我的第二个问题的示例......

4

1 回答 1

20

1.如果您真的需要不惜一切代价始终保持服务器和客户端之间的开放连接,您的方法是可以的。但是,我会使用异步连接,例如向服务器发送 HTTP 请求,然后在服务器愿意时得到回复。

如果您需要服务器稍后回复客户端,但您不知道何时回复,您还可以查看Google Cloud Messaging 框架,它为您提供了一种透明且一致的方式来向您的客户端发送小消息你的服务器。

在开发移动应用程序时,您需要考虑一些事情。

  1. 智能手机没有无限量的电池。

  2. 智能手机的互联网连接有些不稳定,您会在不同的时间失去互联网连接。

当您一直与服务器保持直接连接时,您的应用程序会不断发送保持活动数据包,这意味着您会很快将手机吸干。当互联网连接与移动宽带一样不稳定时,您有时会失去连接,需要从中恢复。因此,如果您使用TCP是因为您想确保收到您的数据包,您将多次重新发送相同的数据包,因此会产生很多开销。

此外,如果您自己在服务器上打开线程,您可能会遇到服务器端的线程问题,这听起来很像。假设您有 200 个客户端同时连接到服务器。每个客户端在服务器上打开 1 个线程。如果服务器需要同时为 200 个不同的线程提供服务,那么这最终对服务器来说可能是一项相当消耗性能的任务,而且您还需要自己做很多工作。

2.退出应用程序后,您需要进行清理。这应该在您激活的onPause方法中完成。Activity

这意味着,关闭所有活动线程(或至少中断它们),保存 UI 的状态(如果需要)并刷新和关闭与您拥有的服务器的任何打开连接。

就使用Threads而言,我建议使用一些内置线程工具,如Handlers或实现AsyncTask

如果你真的认为这Thread是要走的路,我肯定会推荐使用单例模式作为线程的“管理器”。

Thread该管理器将控制您的线程,因此即使您在应用程序的另一部分,您也不会在任何给定时间与服务器进行多次对话。

Application类实现而言,请查看Application 类文档

需要维护全局应用程序状态的基类。您可以通过在 AndroidManifest.xml 的标签中指定其名称来提供自己的实现,这将导致在创建应用程序/包的进程时为您实例化该类。

通常不需要子类化 Application。在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。

因此,建议您不要实现自己的Application类,但是如果您让其中一个Activities初始化您自己的Singleton类来管理Threads和连接,您可能(只是可能)遇到麻烦,因为单例的初始化可能会“绑定”到特定的Activity因此,如果Activity从屏幕上删除特定对象并暂停它可能会被杀死,因此单身人士也可能会被杀死。所以在你的实现中初始化单例Application可能会很有用。

对不起,文字墙,但你的问题是相当“开放式”,所以我试图给你一个有点开放式的问题 - 希望它有所帮助;-)

于 2013-08-18T22:40:36.337 回答