我得到「NetworkOnMainThreadException」的AsyncTask和UDP數據包
我從的AsyncTask 但從感應器事件發送UDP數據包,我的猜測是,感應器事件的主UI線程上觸發。
我想送UdpPackets當新的值可以從傳感器,究竟是因爲我不能從傳感器事件做到這一點的最佳方式?
我得到「NetworkOnMainThreadException」的AsyncTask和UDP數據包
我從的AsyncTask 但從感應器事件發送UDP數據包,我的猜測是,感應器事件的主UI線程上觸發。
我想送UdpPackets當新的值可以從傳感器,究竟是因爲我不能從傳感器事件做到這一點的最佳方式?
爲每個傳感器事件產生一個線程不是很好,並且有一個單獨的線程來輪詢新數據也有問題(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();
被調用,這將使輪詢器線程繼續
更改目標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);
從@RaghavSood答案是確實固體(投票了),但我想你應該儘量避免的變通方法。所以基本上以下是拉格哈夫斯答案的擴展。
我的解決方案將包括隊列或堆棧,你收集你的傳感器數據和每x秒(不縮小間隔),你應該開始您的AsyncTask和將數據發送到服務器。這有一個好處:
和一個缺點:
傳感器事件監聽器掛鉤設置更新的頻率,所以我想以這個速度觸發Udpo數據包,如果有獨立的線程,我將不得不在每個新數據之間插入那個線程,以免捱餓CPU內核。我主要是一個.NET開發人員,在那裏你可以使用傳感器線程中的AutoResetEvent同步線程,然後你可以執行resetEvent.Set()和udp線程執行resetEvent.Wait(),它會在那裏等待Set方法被執行。這樣我就可以保持傳感器事件頻率而不會侵入很多額外的代碼 – Anders
然後使用線程而不是AsyncTask,然後開火。但請記住,服務器也需要能夠處理數據。這意味着如果你發佈這個應用程序,並有千位用戶,你可能會得到一些沉重的服務器負載... – WarrenFaith
嗯,我不想開槍,當傳感器事件發射時,我想開火,因爲我不能從傳感器事件我需要一些sycjing這兩個線程的方式,CyclicBarrier可能會這樣做,只是看着它 – Anders
爲什麼downvote? –
我不是一個,而是這聽起來像一個醜陋的解決辦法,所以我明白爲什麼他們做到了。但是,他們didntr見2)我猜 – Anders
最徹底的方法是做一個回地面線。另外兩個是解決方法,但它們可以工作,但我不會在生產應用程序中推薦它們。 –