2012-09-23 36 views
0

我得到“NetworkOnMainThreadException”的AsyncTask和UDP数据包

我从的AsyncTask 从感应器事件发送UDP数据包,我的猜测是,感应器事件的主UI线程上触发。

我想送UdpPackets当新的值可以从传感器,究竟是因为我不能从传感器事件做到这一点的最佳方式?

回答

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();被调用,这将使轮询器线程继续

1
  1. 更改你的目标SDK以任何低于蜂窝,或魔鬼StrictMode
  2. 产生一个新的线程或的AsyncTask将数据发送到服务器。

更改目标SDK:

<uses-sdk android:minSdkVersion="<your-minimum>" android:targetSdkVersion="9" /> //9 is GB 

魔鬼StrictMode:

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
StrictMode.setThreadPolicy(policy); 
+0

为什么downvote? –

+1

我不是一个,而是这听起来像一个丑陋的解决办法,所以我明白为什么他们做到了。但是,他们didntr见2)我猜 – Anders

+0

最彻底的方法是做一个回地面线。另外两个是解决方法,但它们可以工作,但我不会在生产应用程序中推荐它们。 –

2

从@RaghavSood答案是确实固体(投票了),但我想你应该尽量避免的变通方法。所以基本上以下是拉格哈夫斯答案的扩展。

我的解决方案将包括队列或堆栈,你收集你的传感器数据和每x秒(不缩小间隔),你应该开始您的AsyncTask和将数据发送到服务器。这有一个好处:

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

和一个缺点:

  • 您的数据将发送这意味着你的数据发送不会立即之前收集的。
+0

传感器事件监听器挂钩设置更新的频率,所以我想以这个速度触发Udpo数据包,如果有独立的线程,我将不得不在每个新数据之间插入那个线程,以免挨饿CPU内核。我主要是一个.NET开发人员,在那里你可以使用传感器线程中的AutoResetEvent同步线程,然后你可以执行resetEvent.Set()和udp线程执行resetEvent.Wait(),它会在那里等待Set方法被执行。这样我就可以保持传感器事件频率而不会侵入很多额外的代码 – Anders

+0

然后使用线程而不是AsyncTask,然后开火。但请记住,服务器也需要能够处理数据。这意味着如果你发布这个应用程序,并有千位用户,你可能会得到一些沉重的服务器负载... – WarrenFaith

+0

嗯,我不想开枪,当传感器事件发射时,我想开火,因为我不能从传感器事件我需要一些sycjing这两个线程的方式,CyclicBarrier可能会这样做,只是看着它 – Anders