이동식 저장소

Widget에서 Room 데이터베이스에 접근하는 방법 본문

Primary/Android

Widget에서 Room 데이터베이스에 접근하는 방법

해스끼 2021. 5. 6. 23:15

요약

Room database 객체로부터 DAO 객체를 얻어서 접근한다.

``ViewModel``을 사용할 수 없는 이유

``ViewModel``은 특정 view와 생명주기를 같이 한다. ``Activity``나 ``Fragment``는 ``LifecycleOwner``를 상속받기 때문에 뷰의 생명주기를 관리할 수 있고, 따라서 ``ViewModel``과 함께 사용할 수 있다. 하지만 위젯(``AppWidgetProvider``)은 생명주기가 없다. 그냥 홈 화면에 떠 있기만 한데 무슨 생명주기가 있겠는가?

그럼 어떻게 해야 하나요

``ViewModel``을 사용할 수 없으므로 추상화 단계를 낮춰서 접근해야 한다. ``Repository``를 사용해 보려 했지만, 데이터를 제대로 가져오지 못하는 문제가 있었다.

 

어쩔 수 없지, 더 낮추는 수밖에..

 

``RoomDatabase``를 상속받는 ``Room`` 클래스를 사용할 수밖에 없다. 여기에서 ``DAO (Data Access Object)``를 얻어서 데이터베이스에 접근해야 한다. 일전에 ``Hilt``를 적용해 놨기 때문에 사용하기는 어렵지 않았다.

 

코드를 요약하면 다음과 같다.

@AndroidEntryPoint
class VocaWidgetProvider : AppWidgetProvider() {

    // 데이터베이스 객체
    @Inject
    lateinit var vocaDatabase: RoomVocaDatabase

    // 코루틴 실행용
    private val job = SupervisorJob()
    private val coroutineScope = CoroutineScope(Dispatchers.Main + job)

    override fun onReceive(context: Context, intent: Intent) {
        super.onReceive(context, intent)
        coroutineScope.launch {
            vocaDatabase.vocaDao()?.loadAllVocabulary()?.collectLatest {
                // 업데이트 작업
            }
        }
    }

    override fun onDisabled(context: Context?) {
        super.onDisabled(context)
        job.cancel()
    }

}

 

Comments