1

画面上のオブジェクトの移動に関するデータを格納するために配列リストを使用しています。これは、レンダラーとロジックが別々のスレッドで実行されているためだと思われますが、データがリストから削除されると、indexOutOfBoundsException が発生することがあります。try/catch を含め、これを回避するために考えられるすべての手順を実行しましたが、それでも例外が発生することがあります。これは、例外の原因と思われるレンダラー スレッドの一部です。

public void drawMobs(GL10 gl) {
    boolean playing = MyLaunchActivity.getPlaying();
    if(playing == true){
        try{
             ArrayList<String> mobDat = Play.getMobDat();

        while (currentLoadSpace < mobDat.size()){

        if(!mobDat.isEmpty() || currentLoadSpace < mobDat.size()){

        loadObject = mobDat.get(currentLoadSpace);
        float loadCoordX = Float.parseFloat(mobDat.get(currentLoadSpace + 2));
        float loadCoordY = Float.parseFloat(mobDat.get(currentLoadSpace + 3));

        /*some rendering*/

        currentLoadSpace+=4;
            }
        }
}catch( ArrayIndexOutOfBoundsException e){ Log.d(TAG, "caught");}

    currentLoadSpace = 0;

}}

ご覧のとおり、いくつか試してみましたが、それでもエラーが発生します。エラーログはこちら

01-02 14:02:42.650: E/AndroidRuntime(6947): FATAL EXCEPTION: GLThread 10
01-02 14:02:42.650: E/AndroidRuntime(6947): java.lang.IndexOutOfBoundsException: Invalid index 23, size is 20
01-02 14:02:42.650: E/AndroidRuntime(6947):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at java.util.ArrayList.get(ArrayList.java:308)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at basicmelon.games.agameofsorts.LoadLevel.drawMobs(LoadLevel.java:530)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at basicmelon.games.agameofsorts.MyGLSurfaceRenderer.onDrawFrame(MyGLSurfaceRenderer.java:82)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1429)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1184)
4

6 に答える 6

2

あなたのコードは一貫性がなく、むしろ欠陥があります。たとえば、なぜ同じ条件を 2 回テストするのでしょうか。( currentLoadSpace < mobDat.size())

次に、エラーの原因は次のとおりです。

mobDat.get(currentLoadSpace + 3)

21要素しか含まれていない場合、 23のインデックスを検索しています。したがって、次の行が実際に より小さいことを確認する必要があります。mobDatmobDat.size()

currentLoadSpace + 2

currentLoadSpace + 3
于 2012-01-02T14:23:58.940 に答える
1

考えられる解決策の1つは次のとおりです。

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

これがオプションでない場合は、synchronized(yourList) {} を使用して同時変更を防ぐことができます。

于 2012-01-02T14:23:44.007 に答える
0

ArrayList へのアクセスを同期する必要があると思います。ArrayList はスレッドセーフではありません。IndexOutOfBoundsException をキャッチするのは悪い設計です。この例外は、コードで回避する必要があります。

于 2012-01-02T14:21:13.730 に答える
0

また、currentLoadSpace が mobDat.size() よりも小さいことを確認していますが、currentLoadSpace+3 から取得しようとしていることにも注意してください (このコードに関する限り、範囲外である可能性があります)。

于 2012-01-02T14:27:29.500 に答える
0

arraylist のサイズを確認する必要があります。削除された位置はリストのサイズを超えてはなりません

次のようなことをする必要があります

void avoidArrayIndexOutOfBounds(int position, ArrayList listOfdata){
        if(position>(listOfdata.size()-1)){

            position = listOfdata.size()-1;
        }

    }
于 2012-01-02T14:23:59.090 に答える