1

プレイヤーが加速度計を使用してオブジェクトを移動するマルチプレイヤーゲームをアンドロイドで作成しようとしています。最初に、TCP を使用して、加速度計に接続された onSensorChanged() 内で (SENSOR_DELAY_GAME を使用して)、プレーヤーの X & Y 座標を含むパケットを JSON 文字列として送信していました。しかし、遅延の問題のため、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()また、別のスレッドとして実行する方法があるかどうかも疑問に思っていました...?

4

1 に答える 1

2

最も単純なアプリケーションの場合、簡単に解決できます。

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 ms であるため、同期できないほど長いことがわかりました。もちろん、センサー読み取り値の計算が単純で時間がかからない場合にのみ、正しく機能します。

しかし、全体として、データを計算することonSensorChanged()は良い習慣ではありません。developer.android.com から:

onSensorChanged() メソッドをブロックしない

センサー データは高速で変化する可能性があります。これは、システムが onSensorChanged(SensorEvent) メソッドを頻繁に呼び出す可能性があることを意味します。ベスト プラクティスとして、 onSensorChanged(SensorEvent) メソッド内で行うことはできるだけ少なくして、ブロックしないようにする必要があります。アプリケーションでデータのフィルタリングやセンサー データの削減が必要な場合は、 onSensorChanged(SensorEvent) メソッドの外でその作業を実行する必要があります。

したがって、私が提案するのは、センサー データを何らかのデータ コンテナー (つまりList、sth...) に入れ、別のスレッドからこのデータにアクセスし、計算して送信することです。

最後の質問:onSensorChanged()別のスレッドで実行する方法があったとしても、一度に数千のスレッドが発生する可能性があるため、ほとんどのアプリケーションにとって致命的です (私に関する限り、Java は非常に制約のある環境であり、 API レベルにはすでに重要なエラー防止メカニズムがあります)。

于 2013-04-17T18:03:12.170 に答える