2012-09-23 89 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