【问题标题】:Android - synchronizing threads with onSensorChanged to send udp PacketsAndroid - 使用 onSensorChanged 同步线程以发送 udp 数据包
【发布时间】:2013-04-09 05:52:12
【问题描述】:

我正在尝试在 android 上制作多人游戏,其中玩家使用加速度计来移动物体。最初,我使用 TCP 发送包含播放器 X 和 Y 坐标作为 JSON 字符串的数据包,在附加到加速度计的 onSensorChanged() 内(使用 SENSOR_DELAY_GAME)。但由于延迟问题,我决定尝试 UDP。

现在早些时候,我创建了一个单独的线程来创建一个新的套接字,我使用了以下代码:

public void onSensorChanged(SensorEvent event) {
// Other Stuff
    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
                    out.println(coords.toString());
}

我有:

socket = new Socket(serverAddr, Port);

在另一个线程中。

由于NetworkOnMainThreadException,UDP没有提供任何这样的方法从主线程发送数据,我想我必须在另一个线程中进行数据包传输。但问题是我正在计算要在onSensorChanged() 内部发送的数据,并且我想在每次调用onSensorChanged() 时发送一个数据包。

我对 Java 和多线程比较陌生,并尝试阅读有关同步的内容,但在这里似乎无法正确理解和实现它。因此,如果有人能指出解决此问题的方法,我将不胜感激。 我还想知道在每个 SensorChange 发送坐标是否是个好主意,以及是否有办法优化数据,以便我仍然可以使用 TCP 而不会出现延迟问题。而且我还想知道是否有任何方法可以让onSensorChanged() 作为单独的线程运行...?

【问题讨论】:

    标签: java android multithreading sockets udp


    【解决方案1】:

    对于最简单的应用,可以轻松解决:

    DatagramSocket socket;
    
    public void onSensorChanged() {
        //calculate and create DatagramPacket here
        new Thread(new Runnable() {
            @Override
            public void run() {
                socket.send(packet);    
            }
        });
    }
    

    它不漂亮,但它有效(onSensorChanged() 中的任何计算都不是公平的......)。问题是,发送线程是否必须与onSensorChanged() 方法同步。我发现,当使用 SENSOR_DELAY_GAME 时,我的 SGS3 上的采样频率约为 20 毫秒,因此它足够长而不会同步。 当然,只有当您对传感器读数的计算简单且不耗时时,它才能正常工作。

    但是,总而言之,计算onSensorChanged() 中的任何数据都不是一个好习惯。来自 developer.android.com:

    不要阻塞 onSensorChanged() 方法

    传感器数据可以高速变化,这意味着系统可能会调用 onSensorChanged(SensorEvent) 方法很常见。作为最好的 练习,你应该在 onSensorChanged(SensorEvent) 方法,因此您不会阻止它。如果你的 应用程序要求您进行任何数据过滤或减少 传感器数据,您应该在 onSensorChanged(SensorEvent) 方法。

    因此,我建议将传感器数据放入某个数据容器(即List 或...),然后从另一个线程访问这些数据,计算并发送。

    对于最后一个问题:即使有一种方法可以在单独的线程中运行 onSensorChanged(),这对大多数应用程序来说也是致命的,因为一次可能有数千个线程(就我而言, Java 是一个非常受限制的环境,并且在 API 级别已经有重要的错误预防机制。

    【讨论】:

    • 谢谢。您的回答也让我意识到我用大量不必要的计算阻塞了 mainUiThread - 将它们移到单独的线程显着提高了性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多