android - 使用服务的 TCP 连接

标签 android service tcp connection client

我必须实现一个应用程序。此应用程序使用 TCP/IP 与服务器通信。我的应用程序必须向服务器请求位置。因为应用程序必须留下来监听服务器请求,我认为使用 IntentService。所以我实现了它:

public class Tasks extends IntentService{
public final int SERVERPORT = 8100;
private Socket socket;
PrintWriter out;
BufferedReader in;

public Tasks()
{
    super("My task!");
}
protected void onHandleIntent(Intent intent)
{
    try
    {
        InetAddress serverAddr = InetAddress.getByName("10.0.0.138");
        socket = new Socket(serverAddr, SERVERPORT);
        out = new PrintWriter(socket.getOutputStream());
        //send the request to authenticate it
        out.print("Hello man");
        out.flush();

        //now i need to receive the request Hello_ACK

        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String mServerMessage = in.readLine();

        if(mServerMessage.equals("Hello_ACK"))
         Log.d("show","connection completed");

        //now how can I send KEEP_ALIVE message to server?
        out.print("KEEP_ALIVE");
        out.flush();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }   }  }

我想问你几个问题: 1. IntentService如何维护与服务器的TCP连接? 2. 我必须每 5 分钟向服务器发送一次“KEEP_ALIVE”消息。我该怎么说呢? 3.我已经实现了维护与服务器连接的任务;为了在服务器上调用位置,我是否需要使用一个新线程(例如,一个新类扩展了 Runnable)? 4. 使用 asynctask 做同样的工作是错误的吗? 5.为了与主UT通信,我必须实现一个RegisterReceiver,这是错误的吗? 感谢您的帮助。

最佳答案

阅读您的说明后:

  • 使用 IntentService 本身就没问题。请注意,IntentService 创建了一个工作线程来处理传入的 Intent 。

  • 在您的服务启动时或在您第一次收到 Intent 时延迟创建套接字。不要像现在这样每次收到新的 Intent 时都重新连接/重新创建套接字。只需重新使用现有的套接字即可。但是,您可能希望在连接断开时添加对重新连接套接字的支持(即当您收到 IOError 时)。延迟创建套接字可能更可取,因为您将在正确的线程(即 Intent 处理程序线程)中执行此操作。见下文。

  • 您不需要单独的线程来等待传入的数据。只需在您已经免费获得的 Intent 处理程序线程中执行此操作即可。传入的 Intent 将排队,您的服务将一个接一个地处理它们。

  • AsyncTask 对很多人来说有点困惑。与 postDelayed() 不同,AsyncTasks 是真正的后台操作,带有用于同步框架操作的附加 Hook 。最初,AsyncTasks 在单独的线程中异步执行。 DONUT引入了线程池和HONEYCOMB回到单线程以避免常见的竞争条件。

    服务有点不同。创建新服务并不意味着该服务确实在其自己的线程中运行。相反,对于典型的用例,创建主 Activity 和新创建的 Service 共享同一个线程,等待传入消息。在 UI 线程上执行阻塞(例如网络 IO)操作肯定会使您的应用程序无响应(这就是 Android prevents it by default 的原因)。

  • 对于 keep-alives,您可以简单地在您的服务中使用 Handler.postDelayed()。 (参见 Android run a Task Periodically)。如果您在 Intent 处理程序线程(即 IntentService 为您创建的线程)上创建处理程序,您甚至不必担心并发访问。

  • 从您的服务向任何 Intent 发送者发送回复的最简单方法是使用 Context.sendBroadcast()。要使用它,请使用 Context.registerReceiver() 为您的 Activity 注册一个 BroadcastReceiverBroadcastReceiver 将接收所有与过滤器匹配的 Intent。通常的方法是为 Intent 想出一个唯一的操作名称并以此进行过滤。

[编辑] 关于 AsyncTask 处理的正确声明。

关于android - 使用服务的 TCP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28876171/

相关文章:

Android Retrofit - 如何覆盖 baseUrl

java - 创建通知android未在手机中显示

Android intent.putExtra() 从服务到 Activity

android - GcmListenerService.onMessageReceived 未调用

java - 通过代理进行实时视频流传输

android - 第一次运行 'react-native run-android' 时,出现此错误 :

android - 我什么时候应该在 Android 中使用 FACTORY_TEST 权限?

c# - 可以ping通网络设备但没有tcp连接

android - 如何在 Android 应用程序中使用 Google autocomplete places api

linux - 使用 setsockopt() 修改 TCP 中的内核结构?