为基于 Socket 的 Android 应用程序创建非冻结 UI 的理想方法

Posted

技术标签:

【中文标题】为基于 Socket 的 Android 应用程序创建非冻结 UI 的理想方法【英文标题】:Ideal way to create non-freezing UI for Socket-based Android app 【发布时间】:2012-06-28 02:38:00 【问题描述】:

我正在开发一个使用 Socket 与我的应用服务器通信的 android 应用(用 Java 编写,也使用 ServerSocket)。

在我用来为客户端 Sockets 制作的控制台程序中,我有一个循环继续运行并处理来自服务器的所有消息(一系列 writeObject()readObject() 往返对象流Socket)直到某个消息到来(例如bye),该消息终止循环。

由于控制台程序不涉及任何冻结问题,因此它在那里运行良好。但是我的应用有一个 Activity,它将根据来自服务器的消息更新 UI,如果我采用相同的方法,显然会冻结。

那么,在不挂起游戏 UI 的情况下,处理这种不断处理从服务器接收到的消息的无限循环的理想方法是什么。

P.S.:我知道这无关紧要,但我正在 Android 应用程序和服务器之间以 JSON 格式交换数据。此外,我们将不胜感激提供解释该建议的示例。

谢谢。

【问题讨论】:

你可能会觉得这很有趣,因为你提到了它:androiddesignpatterns.com/2012/06/… 也就是说,听起来您确实想使用Service 而不是AsyncTaskAsyncTasks 用于单个操作,而Services 更多地处理像您描述的那样的连续、长期操作。请记住在退出游戏时取消注册Service,因为如果您不小心,即使在您的应用关闭后Services 也会持续存在。 @AlexLockwood:我是 Android 新手,如何从 Service 中访问我的 Activity 组件(视图和布局)?另外,我在 Activity UI 上有按钮,它具有单击事件处理程序,当被点击时,它们会将一些数据发送到服务器,在这种情况下,服务将如何作为处理发送和接收处理数据的媒介往返服务器? 【参考方案1】:

推荐使用AsyncTaskAsyncTask 主要用于进行这种类型的服务器交互。您也可以使用Service 与服务器进行持续交互。

相关链接:

对于 AsyncTask - http://developer.android.com/reference/android/os/AsyncTask.html

对于服务 - http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

【讨论】:

我浏览了AsyncTask 并且读到我应该将永远循环保留在其dodoInBackground() 方法中,但我不明白是否要单独扩展 AsyncTask类,如何从那里访问我的主要活动方法? 您可以使用doInBackground() 中的publishProgress() 方法来更新您的用户界面。 publishProgress() 将在内部调用 onProgressUpdate(),它在 UI 线程上运行。 我不明白如何使用publishProgress() 访问我的主要活动的视图和布局。 :-/ OP 提到了“循环”和“从服务器连续获取”……AsyncTask 无法做到这一点。您可以将 AsyncTask 用于单个 http 请求或远程数据库连接,但不能用于连续的长期连接。 如果你有自己的扩展AsyncTask的类,你总是可以使用这个类的构造函数传递你的活动的引用。【参考方案2】:

您可能希望在其自己的线程上为此使用Service,纯粹用于网络和数据处理。

然后,您可以将此服务绑定到您的主应用程序,并从/向它发送接收消息。这是一个关于这个主题的相当不错的教程:Service Tutorial

【讨论】:

以上是关于为基于 Socket 的 Android 应用程序创建非冻结 UI 的理想方法的主要内容,如果未能解决你的问题,请参考以下文章

基于Socket的Android聊天室

基于Socket的Android聊天室

Android中基于Socket的网络通信

Android 基于UDP的Socket通信

Android 上的 WebSockets 与 Android 中的 socket.io

Android之Socket的基于UDP传输