1

我正在尝试在 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);

在另一个线程中。

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

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

4

1 回答 1

2

对于最简单的应用程序,它可以很容易地解决:

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 级别已经有重要的错误预防机制)。

于 2013-04-17T18:03:12.170 回答