본문 바로가기

IT

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.

반응형

ListView를 활용한 프로그래밍을 하는 도중에 자주 볼 수 있는 에러입니다.

저런 에러가 발생하는 경우는 대부분 UI 쓰레드가 아닌 별도로 생성된 멀티쓰레드에서 UI(여기서는 ListView)를 갱신하려고 했을 때 발생합니다.

 인터넷을 검색해 본 결과, UI쓰레드에서 갱신할 수 있게끔 하라는 겁니다.

 저에겐 위의 코드를 쓸 이유가 없었습니다. 왜냐하면 저 리스트뷰를 갱신하게 하는 함수를 대부분 UI쓰레드에 해당하는 핸들러에서 처리를 했기때문입니다. (쓰레드와 핸들러와의 관계는 검색하시길..)


 그러기에 제대로 작동하고 있던 리스트뷰와 그렇지 않은 리스트뷰의 ArrayList를 사용하는 소스를 보기 시작했습니다. 그러던 중에 다음과 같은 부분을 발견했습니다. 처리후 정상적으로 작동하였구요...


 오류가 발생하는 부분은 다음과 같은 부분이었습니다.

 위의 코드를 보면 al_Statement 라는 ArrayList가 보입니다. 저는 이자료를 ListView에 보여주는 데이터변수로 사용중이었습니다. 그런데 단순히 자료를 비우는 clear()함수를 쓰레드 내부에서 사용하었던 것으로 에러가 발생하였습니다. 아마도 예상컨데, 저 clear()함수가 수행되면서 ListViewAdapter에 영향이 가지 않았나 싶습니다. (정확한 의견은 아닙니다. 다만 저의 의견일 뿐입니다.)


 al_Statement.clear() 함수를 쓰레드가 시작하기 전의 UI쓰레드 부분으로 끄집어 내었습니다. 그리고 약간의 코드를 좀 추가해서 수정하였습니다. 명시적으로 작동하길 바라면서...

 이렇게 처리한 이후로는 에러가 발생하지 않는군요.. ListViewAdapter를 생성하면서 그 리스트뷰에서 사용되는 변수도 함부로 UI쓰레드가 아닌 쓰레드에서 다루면 안된다는 것을 알게 되었습니다. 끝.

반응형