안드로이드

3.0 허니컴 이후 버전에서의 CursorAdapter 에서 MergeCursor 사용 버그

raulyo 2012. 4. 23. 17:24

3.0 이후 버전에서 CursorAdapter에 커서 두개이상을 조합한 MergeCursor 사용시 버그가 있습니다.


처음 데이터 표시는 잘되지만 데이터 변경이 일어나 커서가 갱신될 때 CursorIndexOfBoundsException 이 일어납니다.


ICS가 올려진 폰을 쓰시는분들중에 가끔 어떤 앱에서 데이터를 추가하거나 수정하면 갑자기 오류메세지가 뜨면서


꺼지는 경우를 보셨을 겁니다. 다 CursorAdapter에 MergeCursor를 사용한 어플들 입니다.


에러로그를 보고 제가 추측해보건데 데이터가 갱신되면 소속된 Cursor 모두의 requery()가 일어난 이후에


즉 MergeCursor에 속한 Cursor들이 모두 완성되고 나서 Adapter가 갱신 되야 하는데 그렇지 않고 첫번째 커서가


완성되고 다른커서들을 받아오는 과정에서 갱신하려다보니 컬럼을 찾지 못해 생기는 버그인듯 합니다.



이것을 해결할 수 있는 방법으로 몇가지가 있겠는데 CursorAdapter의 getItemId()메서드를 오버라이딩해서


CursorIndexOfBoundsException를 try catch에서 잡아서 무시해버리는 방법이 있고


그러나 이경우는 혹시나도 일어날 수 있는 CursorIndexOfBoundsException에 대한 예외를 모두 이것으로 간주해


버린다는 위험요소가 존재합니다.



또하나는 MergeCursor를 쓰지 않고 쿼리를 날릴 때 Cursor를 두개 이상 받아서 합치는 대신 UNION을 이용하는 방법이


있습니다. 이경우는 MatrixCursor 같은 커서나 혹은 Cursor를 상속받아 재정의한 커서들에 대한 활용을 할 수 없다는 단점이


존재합니다.


 
댓글
2012.01.12 19:58:05
커니

흠... ICS에서 구글이 급했는지 버그들이 꽤나 보이네요....

HttpURLConnection 버그는 아무것도 아니였군요 ㅠ.ㅠ

댓글
2012.01.12 21:23:15
동네가수

매 버전마다 버그들은 어느정도 있어왔는데 이건 보니까 허니컴에서도 있던 버그인데 왜 못고쳤는지 생각해보니

MergeCursor 자체를 별로 쓸일이 생각많큼 많지는 않더군요 근데 써보면 바로나오는 버그이기도 해서 허니컴으로

얼마나 개발을 안했는지 알것같네요 ㅠㅠ


하긴 구글링 해봐도 이 이슈에 대해 이야기 하는사람 한명밖에 없더군요 그것도 ICS에서 적용해보다가 발견한거니

허니컴은 그냥 지나친거겠죠 ㅋ 메일 보내놨으니 다음 마이너 업데이트에서 고쳐지겠죠 

댓글
2012.01.17 10:03:45
볼레로

MergeCursor 쓰지 말라고 내용이 찾아보시면 있을 거예요. 


허니컴 이상을 생각하시면 이것은 버리셔야 합니다. 

댓글
2012.01.17 10:29:41
동네가수

그 내용을 어디서 보셨는지는 모르겠지만 허니컴 API 문서를 보면 MergeCursor에 getType 메서드가 추가됩니다. 쓰임을 권장하지 않는 클래스에 메서드를 추가하는 경우는 거의 없다고 생각됩니다. 개인적인 생각으로는 쓰지말라고 권장하는건 아닌듯 합니다. MergeCursor를 썼을 때 딱히 문제 되는 점도 모르겠구요 구글에서 정말로 권장하지 않는다면 @Deprecated 태그를 달아 뒀겠죠



댓글
2012.01.18 11:01:29
볼레로

아  MergeCursor가 아니라  


ManagedQuery 였네요. 

http://developer.android.com/reference/android/app/Activity.html#managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)



댓글
2012.01.18 12:57:02
동네가수

아 managedQuery() 같은 경우는 저도 요즘 동작이 이상해져서 쓰지 않고 있어요 그냥 onDestroy에서 Cursor를 close() 해주던지 혹은 CursorLoader로 Cursor를 관리하는게 좋을거 같더군요