2013-04-16 91 views
1

我正在嘗試在Android中製作多人遊戲,其中玩家使用加速度計移動對象。最初,我使用TCP將包含播放器Y座標的數據包作爲JSON字符串發送,該數據包位於附加到加速度計(帶有SENSOR_DELAY_GAME)的onSensorChanged()內部。但由於延遲問題,我決定試用UDP。Android - 使用onSensorChanged同步線程以發送udp數據包

現在早些時候,我創建了創建了一個新的插座單獨的線程中,我用下面的代碼:

public void onSensorChanged(SensorEvent event) { 
// Other Stuff 
    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true); 
        out.println(coords.toString()); 
} 

而且我有:

socket = new Socket(serverAddr, Port); 

在另一個線程。

由於UDP不提供任何這樣的方法來發送數據從主線程由於NetworkOnMainThreadException,我想我必須在另一個線程中執行數據包傳輸。但問題是我正在計算在onSensorChanged()內部發送的數據,並且每次調用onSensorChanged()時我都希望發送數據包。

我對Java和多線程相對較新,並嘗試閱讀關於同步的內容,但似乎無法正確理解和實現它。所以,如果有人能指出解決這個問題的方法,我將不勝感激。 我也想知道是否發送每個SensorChange的座標是一個好主意,以及是否有一種方法來優化數據,以便我仍然可以使用TCP而不會出現延遲問題。我還想知道是否有任何可能的方法使onSensorChanged()作爲一個單獨的線程運行......?

回答

2

對於simpliest應用程序,它可以很容易解決:

DatagramSocket socket; 

public void onSensorChanged() { 
    //calculate and create DatagramPacket here 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      socket.send(packet);  
     } 
    }); 
} 

這不是很漂亮,但它的工作原理(在onSensorChanged()任何計算不漂亮是公平的......)。問題是,發送線程是否必須與onSensorChanged()方法同步。我發現,當使用SENSOR_DELAY_GAME時,我的SGS3上的採樣頻率大約是20毫秒,所以它足夠長,不能同步。 當然,只有您的傳感器讀數計算簡單且不耗費時間,它才能正常工作。

但總而言之,計算onSensorChanged()中的任何數據都不是一個好習慣。從developer.android.com:

不要阻塞onSensorChanged()方法

傳感器數據可以高速率,這意味着該系統可以調用 的onSensorChanged(SensorEvent)方法經常改變。作爲最佳實踐,您應儘可能少地使用onSensorChanged(SensorEvent)方法,因此您不會屏蔽該方法。如果您的 應用程序需要您執行任何數據過濾或減少 傳感器數據,則應該在onSensorChanged(SensorEvent)方法之外執行該工作。在一些數據容器

所以我的建議是把傳感器數據(即List或某事...),並從另一個線程訪問這些數據,計算併發送。

對於最後一個問題:即使有一種方法可以在單獨的線程中運行onSensorChanged(),但對於大多數應用程序來說,這可能是致命的,因爲一次可能有數千個線程(就我而言,Java是相當有限的環境,並且已經在API級別上具有重要的防錯機制)。

+0

謝謝。你的回答也讓我意識到,我用大量不必要的計算堵塞了mainUiThread - 將它們移動到單獨的線程可顯着提高性能。 – Erric