Android Paging3 , Room , Flow 관련 백그라운드 쓰레드

2022. 5. 4. 15:52Android

반응형

필자는 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 프로젝트를 참고하여 이것저것 시도를 해보았다

 

하지만 실패를 하였고 다시 구글 검색을 하던도중 드디어 원하는 답을 찾았다.

 

https://stackoverflow.com/questions/63166046/why-do-i-get-cannot-access-database-on-the-main-thread-since-it-may-potentially - 출처

 

문제의 코드를 보겠다.

 

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일에 걸쳐서 해결한 문제다. 어차피 개인프로젝트라 시간은 널널하긴 하지만

 

이번 계기로 굉장히 많은 도움이 된거같다.

 

혹여나 나와 같은 문제를 겪는 사람이 있어서 이 글을 보게되어 문제가 해결되었으면 좋겠다. 

반응형