5

Android でゲーム「Space RPG」を開発しています。現在、このエラーはほとんどの Galaxy S4 と HTC One でのみ表示されます。これはすべて Java です。

プロセスをデバッグして問題のスレッドを一時停止しようとすると、ゲームが停止し、一時停止せず、スピンオン一時停止エラーが発生します。スレッド ダンプを見ると、目的の「終了位置」を取得し、「開始位置」を見つけるために増加する距離ステップで逆方向に反復している特定の while ループ内にあることがわかります。

これは、物事が面倒になるところです。条件が while(true) であっても、ループが無期限に実行できないことを確認できます。ブレークが呼び出される前に、おそらく 200 回を超える反復を実行することはできません (このアサーションは、作業中のコードによってバックアップされています)。私が試した他のすべての電話)。

この問題を解決するために、単純なインクリメント変数をループ内に追加しました。変数が 1000 を超えると、何かがログに記録されるため、変数が設定されている場合に備えて、DID が何度も実行されたことがわかります。ひどいか何か。 このカウンター コードが存在する場合、クラッシュ/ハングは発生しません。また、1000 回以上実行されたことを示すログも表示されません。

このカウンターを削除すると、5 秒から 10 秒の再生後に毎回ハングが発生します [while ループは 10 回程度実行されますが、状況によって異なります]。

したがって、私の質問は、一体何が起こっているのですか? :P なぜこれらの新しい携帯電話 (しかし、古い携帯電話にはないように見える) は、そこにインクリメントされた変数がない場合、有効な作業を行っているループに問題があり、長くは続かないのですか? スレッドがそのループで停止する可能性はありますか? また、カウンター変数を追加すると問題がどのように修正されるのでしょうか? この作業は、重要な場合に備えて、opengl レンダリング スレッドで行われています。

ほとんどの S4 でこれが発生したという報告がありますが、発生しなかった S4 が少なくとも 1 つあります。私が今日使用しているものは、それが起こっています。これは、電話の特定のAndroid、Java、dalvikなどに関係している可能性があるのではないかと思いますが、残念ながら、それが機能したS4からの詳細はありません.

このようなものについてのヘルプ、ガイダンス、考え、またはさらに読んでいただければ幸いです。どうもありがとうございました。

float vel = 1.0f; // final velocity is 1. We are working backwards to find out what the starting velocity will need to be.
int i = 0;
double xmath = Math.sin(rot* (Math.PI/180.0f)); // component of velocity for x,y direction based on rotation
double ymath =  Math.cos(rot* (Math.PI/180.0f));
while (true) {
        /* with this section uncommented, the stall never happens...
         ++i;
        if (i>1000) {
            // Something went rather wrong
            vel = 91.0f; // LOG WAS HERE, now has a fallback value justincase
            break;
        }
        */
        vel *= 1.2f;            
        dx -= vel* xmath;
        dy += vel* ymath;           
        if (distance < (float)Math.sqrt(dx*dx+dy*dy)) {
            break;
        }
}
// Give the ship a velocity that is appropriate for the distance remaining
_AI.Ship.Velocity = vel;
4

1 に答える 1

3

これはおそらくhttp://b.android.com/58726です。

バグには完全な詳細があります。つまり、一部のベンダーは Dalvik VM の修正版を使用しているようです。JIT コンパイラに加えられた変更により、特定の状況でスレッドの中断が発生しなくなりました。

この問題のリトマス試験紙は、GS4 および HTC1の「純粋な Android」 Google Play エディションと標準の小売デバイスを比較することです。前者が壊れた動作を示し、後者が正しく動作する場合は、ベンダー固有の問題が発生している可能性があります。

回避策は、あなたが行ったことを実行することです: コードの効率を下げて、「最適化された」ケースに陥らないようにします。理想的には、アプリは問題のないデバイスに対して別のコード パスを実行時に選択しますが、実行時に問題を検出する良い方法はわかりません。

于 2013-09-22T15:48:09.577 に答える