我收到“NetworkOnMainThreadException”
我正在从 AsyncTask 发送 UDP 数据包,但从Sensor 事件中,我猜测 Sensor 事件在主 UI 线程上触发。
我想在传感器提供新值时发送 UdpPackets,因为我无法从传感器事件中做到这一点,所以最好的方法是什么?
我收到“NetworkOnMainThreadException”
我正在从 AsyncTask 发送 UDP 数据包,但从Sensor 事件中,我猜测 Sensor 事件在主 UI 线程上触发。
我想在传感器提供新值时发送 UdpPackets,因为我无法从传感器事件中做到这一点,所以最好的方法是什么?
@RaghavSood 的答案确实是可靠的(投票赞成),但我认为你应该尽量避免变通方法。所以基本上以下是Raghavs答案的2.的扩展。
我的解决方案将包括一个队列或堆栈,您可以在其中收集传感器数据,并且每隔 x 秒(不要缩小间隔)您应该启动 AsyncTask 并将数据发送到您的服务器。这有一个优点:
还有一个缺点:
更改目标 SDK:
<uses-sdk android:minSdkVersion="<your-minimum>" android:targetSdkVersion="9" /> //9 is GB
禁用严格模式:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
为每个传感器事件生成一个线程并不是很好,并且有一个单独的线程来轮询新数据也有问题(WarrenFaith 回答)。
我最终使用了一个 CyclicBarrier,就像这样,一个单独的线程内的无限循环
running = true;
worker = new Thread(new Runnable() {
public void run(){
while(running) {
try {
sync.await();
Send();
} catch(Exception e) {}
}
socket.disconnect();
}
});
worker.start();
线程将停止sync.await();
在线
直到传感器提供新数据
SensorEventListener allListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
if(sendOrientation) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = sensorManager.getRotationMatrix(R, I, acc, mag);
if (success) {
SensorManager.getOrientation(R, orientation);
}
}
if(sync.getNumberWaiting() > 0)
sync.reset();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
并被调用,这sync.reset();
将使轮询线程继续进行