2022. 5. 4. 15:52ㆍAndroid
필자는 Android 를 개발하면서 MVVM 아키텍처 패턴과 더불어
Jetpack 관련 라이브러리들을 많이 사용을 해보고 있었다
그중에서 Room . Paging3 , Flow 를 사용하면서 굉장히 난제 였던 문제가 있었다
상황은 이렇다 앱이 켜지고 로컬 DB에 있는 데이터를 화면에 뿌려주려고 하는데 문제가 생겼다
그것은 메인 쓰레드 관련 문제였다.
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
이런 오류를 굉장히 많이 봤다
저것도 간단하게는 " db에 접근할때 메인쓰레드를 쓰지마라 잘못하다가 UI 가 잠길수있다"
이건데 참 난해 하였다 그리하여 찾아보니
Room 설정 할때
.allowMainThreadQueries()
이런 옵션이 있었다 이것의 기능은 메인쓰레드를 허용하겠다 이다
처음 저 옵션을 사용하기에 먼가 찝찝한 기분이 들어서 사용을 하지 않고 계속 구글링을 했다
하지만 검색 능력이 부족한 탓인지 Paging3 + Room + Flow 를 사용한 게시글들을 잘 찾지를 못했다
그렇다고 LiveData 를 쓰자니 구글에서 Flow 를 굉장히 밀고있던데 이건 포기 못하겠고 싶어서
할수없이 Room 메인쓰레드를 허용하기로 하고 대충 마무리를 지었다
그리고 시간이 좀 흐르고 재밌는 프로젝트가 생각나 혼자서 프로젝트를 진행하던중 또 다시 저 문제에 마주치게되었다.
이번에는 꼭 성공해보자 하고 구글에서 만든 SunFlower 프로젝트를 참고하여 이것저것 시도를 해보았다
하지만 실패를 하였고 다시 구글 검색을 하던도중 드디어 원하는 답을 찾았다.
문제의 코드를 보겠다.
fun getPagingData() : Flow<PagingData<StorageMaterialData>>{
return repository.getPagingStorage().cachedIn(viewModelScope)
}
보면 cachedIn(viewModelScope) 라고 되어있는곳이 있다.
스택오버플로우 에 의하면 viewModelScope 은 메인쓰레드를 사용하게끔 설계되어있던것이였다.
여태 이것을 몰라 헤메고있었다.
설마 하는 마음으로 코드를 바꿧다.
fun getPagingData() : Flow<PagingData<StorageMaterialData>>{
return repository.getPagingStorage().cachedIn(CoroutineScope(Dispatchers.IO))
}
CoroutineScope(Dispatchers.IO 로 바꾸니
굉장히 잘 돌아간다 이것도 2일에 걸쳐서 해결한 문제다. 어차피 개인프로젝트라 시간은 널널하긴 하지만
이번 계기로 굉장히 많은 도움이 된거같다.
혹여나 나와 같은 문제를 겪는 사람이 있어서 이 글을 보게되어 문제가 해결되었으면 좋겠다.
'Android' 카테고리의 다른 글
Android 12 Splash Screen 대응 (0) | 2022.05.18 |
---|---|
Android Hilt 에 대해 정리 (0) | 2022.05.09 |
Android 크롭 기능 없이 이미지 자르기 (0) | 2020.06.29 |
Android 이미지 해상도별 자동 비율 구하기 (0) | 2020.06.29 |
[안드로이드] 각 프래그먼트 별 뒤로가기 버튼(백버튼) 이벤트 (뷰페이저 사용) (0) | 2020.06.15 |