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

您的代码不一致并且相当错误。例如,为什么要测试两次相同的条件?( currentLoadSpace < mobDat.size())

其次,您的错误来自:

mobDat.get(currentLoadSpace + 3)

当仅包含21 个元素时,您正在搜索23的索引。因此,您应该检查以下行实际上是否小于:mobDatmobDat.size()

currentLoadSpace + 2

currentLoadSpace + 3
于 2012-01-02T14:23:58.940 回答
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

您需要检查数组列表的大小。删除的位置不应大于列表大小

您需要执行以下操作

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

            position = listOfdata.size()-1;
        }

    }
于 2012-01-02T14:23:59.090 回答
0

另请注意,您正在检查 currentLoadSpace 是否小于 mobDat.size(),但您正在尝试从 currentLoadSpace+3 中检索(就这段代码而言,它很可能超出范围)。

于 2012-01-02T14:27:29.500 回答
0

我知道已经有答案了,但试着简单地捕捉一个IndexOutOfBoundsException而不是一个ArrayIndexOutOfBoundsException

我建议这样做,因为您正在捕获 Array 异常并且仍然​​得到标准的 Index 异常。这很可能是因为 Index 是一个比 Array 异常“更高/更低”(但是你想看到它)的异常。这意味着您确实捕获了 Array 异常,但除此之外,仍然抛出 Index 异常。

于 2015-02-05T22:51:51.330 回答