0

我收到“NetworkOnMainThreadException”

我正在从 AsyncTask 发送 UDP 数据包,但从Sensor 事件中,我猜测 Sensor 事件在主 UI 线程上触发。

我想在传感器提供新值时发送 UdpPackets,因为我无法从传感器事件中做到这一点,所以最好的方法是什么?

4

3 回答 3

2

@RaghavSood 的答案确实是可靠的(投票赞成),但我认为你应该尽量避免变通方法。所以基本上以下是Raghavs答案的2.的扩展。

我的解决方案将包括一个队列或堆栈,您可以在其中收集传感器数据,并且每隔 x 秒(不要缩小间隔)您应该启动 AsyncTask 并将数据发送到您的服务器。这有一个优点:

  • 您可以防止垃圾邮件数据,包括连接和断开与您的服务器的连接。这应该可以减少手机的功耗并防止服务器被数据淹没。

还有一个缺点:

  • 您的数据将在发送之前被收集,这意味着您的数据发送不会是即时的。
于 2012-09-23T14:23:59.450 回答
1
  1. 将您的目标 SDK 更改为 Honeycomb 以下的任何内容,或禁用 StrictMode
  2. 生成一个新线程或 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);
于 2012-09-23T13:53:23.917 回答
0

为每个传感器事件生成一个线程并不是很好,并且有一个单独的线程来轮询新数据也有问题(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();将使轮询线程继续进行

于 2012-09-24T11:10:40.460 回答