简体   繁体   English

Android-与onSensorChanged同步线程以发送udp数据包

[英]Android - synchronizing threads with onSensorChanged to send udp Packets

I am trying to make a multiplayer game on android in which players use the accelerometer to move an object around. 我正在尝试在Android上制作多人游戏,在该游戏中,玩家使用加速度计来移动物体。 Initially I had used TCP to send packets which contain the X & Y coordinates of the player as a JSON string, inside the onSensorChanged() attached to the accelerometer(with SENSOR_DELAY_GAME). 最初,我使用TCP发送数据包,其中包含播放器的X和Y坐标作为JSON字符串,位于附加到加速度计(带有SENSOR_DELAY_GAME)的onSensorChanged()内部。 But due to latency issues, I decided to try out UDP. 但是由于延迟问题,我决定尝试UDP。

Now earlier, I created a seperate thread which created a new socket and I used the following code: 现在,我创建了一个单独的线程,该线程创建了一个新的套接字,并使用了以下代码:

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

And I had: 我有:

socket = new Socket(serverAddr, Port);

in another thread. 在另一个线程中。

Since UDP does not provide any such methods to send the data from the main thread due to NetworkOnMainThreadException , I figured I have to do the packet transmission in another thread. 由于NetworkOnMainThreadException 由于UDP不提供任何此类方法来从主线程发送数据,因此我认为我必须在另一个线程中进行数据包传输。 But the problem is that I'm calculating the data to be sent inside the onSensorChanged() , and I want to send a packet each time the onSensorChanged() is invoked. 但是问题是我正在计算要在onSensorChanged()内部发送的数据,并且我想在每次onSensorChanged()调用时发送一个数据包。

I'm relatively new to Java and multithreading and tried reading about synchronization, but cannot seem to properly understand and implement it here. 我对Java和多线程还比较陌生,并尝试阅读有关同步的内容,但似乎无法在此处正确理解和实现它。 So I'd greatly appreciate if someone can point out an approach to solve this. 因此,如果有人能指出解决此问题的方法,我将不胜感激。 I'd also like to know if sending the coordinates at each SensorChange is a good idea and whether there is a way to optimize the data so that I can still use TCP without latency issues. 我还想知道在每个SensorChange上发送坐标是否是一个好主意,以及是否有一种方法可以优化数据,以便我仍然可以使用TCP而不会出现延迟问题。 And I was also wondering if there was any possible way to make onSensorChanged() run as a separate thread...? 而且我还想知道是否有任何可能的方法可以使onSensorChanged()作为单独的线程运行...?

For simpliest applications, it can be solved easily: 对于最简单的应用程序,可以轻松解决:

DatagramSocket socket;

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

It's not pretty, but it works (any calculations in onSensorChanged() aren't pretty to be fair...). 它不是很漂亮,但是可以正常工作( onSensorChanged()中的任何计算都不太公平……)。 Question is, whether the sending thread has to be synchronized with onSensorChanged() method. 问题是,发送线程是否必须与onSensorChanged()方法同步。 I figured out, that when using SENSOR_DELAY_GAME, sampling frequency on my SGS3 is around 20 ms, so it is long enough not to be synchronized. 我发现,使用SENSOR_DELAY_GAME时,我的SGS3上的采样频率约为20毫秒,因此它足够长,无法同步。 Of course it would work correctly only if Your calculations of sensor readings are simple and not time-consuming. 当然,只有在您的传感器读数计算简单且不费时的情况下,它才能正常工作。

But, all in all, calculating any data in onSensorChanged() isn't a good practise. 但是,总的来说,在onSensorChanged()计算任何数据onSensorChanged()是一个好习惯。 From developer.android.com: 从developer.android.com:

Don't block the onSensorChanged() method 不要阻塞onSensorChanged()方法

Sensor data can change at a high rate, which means the system may call the onSensorChanged(SensorEvent) method quite often. 传感器数据的更改速度可能很高,这意味着系统可能会经常调用onSensorChanged(SensorEvent)方法。 As a best practice, you should do as little as possible within the onSensorChanged(SensorEvent) method so you don't block it. 最佳做法是,您应该在onSensorChanged(SensorEvent)方法中做尽可能少的操作,以免阻塞它。 If your application requires you to do any data filtering or reduction of sensor data, you should perform that work outside of the onSensorChanged(SensorEvent) method. 如果您的应用程序要求您执行任何数据过滤或减少传感器数据的操作,则应在onSensorChanged(SensorEvent)方法之外执行该工作。

Therefore what I would suggest is put sensor data in some data container (ie List or sth...) and access this data from another thread, calculate it and send. 因此,我建议将传感器数据放入某个数据容器(即List或sth ...)中,并从另一个线程访问此数据,进行计算并发送。

And for the last question: even if there was a way to run onSensorChanged() in separate thread, it would be fatal to most applications, due to possible thousands of threads at one time (as far as I'm concerned, Java is quite restraining environment and there are significant error-preventing mechanisms already on API-level). 最后一个问题:即使有一种方法可以在单独的线程中运行onSensorChanged() ,对于大多数应用程序来说也是致命的,因为一次可能有成千上万的线程(就我而言,Java相当限制环境,并且在API级别上已经有重要的错误预防机制)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM