2011-11-14 8 views
0

AsyncTask 콘텐츠 공급자를 쿼리하고 해당 작업의 onPostExecute()에서 몇 가지 추가 처리를 수행하고 있습니다. 재현하기가 매우 어려운 예외에 대한 스택 추적이 있지만 조건을 방지하거나 코드를 수정하고 싶습니다. 코드는 다음과 같습니다.이 ArrayIndexOutOfBounds 예외가 throw되는 방법에 대해 잘 모르겠습니다.

int i = 0; 
mIds = new long[cursor.getCount()]; 
while (cursor.moveToNext()) { 
    mIds[i++] = cursor.getLong(COLUMN_ID); 
} 

루프의 회선에서 충돌이 발생했습니다.

  1. cursor.getCount() 잘못된 수를 반환 : 만약 내가 볼때,이 일어날 수있는 유일한 방법입니다.
  2. cursor이 루프가 실행되는 동안 변경되지만 이라고 생각할 수 없습니다. cursor은 로컬 변수이기 때문입니다. 아마도 cursor의 기본 요소가 변경된 것으로 알고 있습니다.
  3. mIds이 변경되었습니다. UI 스레드에서 을 실행하고 있기 때문에 가능하지 않습니다.이 변수에 새 값인 이 할당 된 유일한 곳입니다. UI 스레드에서 실행되는 onPostExecute의 특성상이 코드가 다른 시간에 동시에 실행되는 것은 불가능합니다. 맞습니까?

내가 누락 된 항목이 있습니까? 전체 코드를 보지 않고 그 루프에 어떤 문제가 있는지 확인

int i = 0; 
mIds = new long[cursor.getCount()]; 
while (cursor.moveToNext()) { 
    mIds[i] = cursor.getLong(COLUMN_ID); 
    i++; 
} 
+0

그냥 루프 전에 mIds''의 길이를 로그 :

Cursor cursor = null; try { cursor = getDb().rawQuery(query, params); // your call to database here... if (cursor == null || cursor.getCount() == 0) return false; cursor.moveToFirst(); mIds = new long[cursor.getCount()]; int i = 0; do { mIds[i] = cursor.getLong(COLUMN_ID); i++; } while (cursor.moveToNext()) } catch(Exception e) { // Do error handling return false; } finally { closeCursor(cursor); cursor = null; } return true; 

여기 내 접근 방식에 대한 백업입니다. 그런 다음 mIds [i ++]에 대입 할 때 조건부 중단을하고 'i> = mIds.length'이면 중단됩니다. 그것이 깨지면'커서'가 길이를 바꿨 던지 아니면 다른 일이 벌어 질 지에 관계없이'mIds'가 어떻게 든 다시 할당되었는지 확인할 수 있습니다. –

+0

현재이 정보를 기록하지 않고 재현 할 수 없으므로 (하나의 버그 보고서가 있음) 코드를 추가하여 조건을 보호 할 수 있기를 바랍니다. –

답변

1

그것은 어려운하지만 난 docs에서주의 :

+0

모든 답변 중에서, 나는 이것이 가장 가까운 것이라고 생각합니다. 그것은 내가 코드를 조금 더 깊게 보게했다. 루프는 실제로'MyAdapter.changeCursor (cursor)'에서 호출 된 메소드에 있고 루프를 포함하는 메소드는 AFTER'super.changeCursor (cursor)'라고합니다. 'changeCursor()'는'onPostExecute()'에서 호출되는 메소드입니다.이제, 내 생각은'super.changeCursor()'이후에 커서가 어댑터에 액세스하는 다른 스레드에서 사용할 수있게되고 그 스레드는 루프 중에 위치를 재설정해야합니다. –

1

이 시도

커서 구현은 동기화 할 필요가 없습니다 커서를 사용할 때 다중 스레드의 커서를 사용하는 코드는 자체 동기화를 수행해야합니다.

+0

왜 i ++를 움직이는 것이 여기에 영향을 미칠지에 대해 자세히 설명해 주시겠습니까? –

+0

글쎄, 내가 사용하기 전에 그 추가 믿습니다. 그래서 그것은 1에서 (0과 반대로) 시작하여 +1에서 끝나야합니다. 내가 틀릴 수도 있고 시험 앞에 나에게 컴파일러가 없다. –

+1

그건 후위 증가 연산자가 작동하는 방식이 아니야. –

0

나는 항상 이렇게 해왔다. 대부분의 문제를 피하는 것 같습니다.
Is Android Cursor.moveToNext() Documentation Correct?
Does finally always execute in Java?

+0

감사합니다. 그것은 강제 종료를 피할 것이지만, 나는이 예외가 왜 그것을 마스킹하는 것보다 일어나는지 이해하는데 더 관심이있다. –

+0

그래, 항상 이해하는 것이 좋다. 어쨌든, 나는'moveToNext()'에 문제가 있다는 것을 상기 해 본다. 시도해 보라. 이것을하기 전에 : moveToFirst()를 while 앞에 추가하고 do - while으로 바꾼다. 도움이되는지 확인하십시오. 또한'i ++ '를'mIds [i ++]'에서 멀리 가져 가겠습니다. –

관련 문제