Избегание исключений за пределами границ - PullRequest
1 голос
/ 02 января 2012

Я использую Array List для хранения данных о движущихся объектах на экране.Я подозреваю, что это потому, что мой рендер и моя логика работают в отдельных потоках, но иногда, когда данные удаляются из списка, я получаю исключение 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)

Ответы [ 6 ]

2 голосов
/ 02 января 2012

Ваш код несовместим и довольно неисправен.Например, почему вы тестируете дважды одно и то же условие?(currentLoadSpace < mobDat.size())

Во-вторых, ваша ошибка исходит из:

mobDat.get(currentLoadSpace + 3)

Вы ищете индекс 23 , когда mobDat содержит только 21 элементов.Поэтому вы должны проверить, что следующие строки на самом деле меньше mobDat.size():

currentLoadSpace + 2

и

currentLoadSpace + 3
1 голос
/ 02 января 2012

Одним из возможных решений может быть:

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

Если это не вариант, вы можете использовать synchronized (yourList) {} для предотвращения одновременных изменений.

0 голосов
/ 06 февраля 2015

Я знаю, что ответ уже есть, но попробуйте просто поймать IndexOutOfBoundsException вместо ArrayIndexOutOfBoundsException

Я предлагаю это, потому что вы перехватываете исключение Array и все еще получаете стандартное исключение Index. Скорее всего, это связано с тем, что Index является исключением «выше / ниже» (как вы хотите видеть), чем исключение Array. Это означает, что вы действительно поймали исключение Array, но кроме этого Index все еще выбрасывается.

0 голосов
/ 02 января 2012

Обратите также внимание, что вы проверяете, что currentLoadSpace меньше, чем mobDat.size (), но вы пытаетесь извлечь из currentLoadSpace + 3 (что, если рассматривать этот фрагмент кода, вполне может быть внеграницы).

0 голосов
/ 02 января 2012

Вам необходимо проверить размер массива. Удаленное положение не должно превышать размер списка

Вам нужно сделать что-то вроде следующего

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

            position = listOfdata.size()-1;
        }

    }
0 голосов
/ 02 января 2012

Я думаю, что вы должны синхронизировать доступ к вашему ArrayList. ArrayList не является потокобезопасным. Поймать исключение IndexOutOfBoundsException - плохой дизайн. Это исключение следует избегать вашим кодом.

...