예전 포스팅에서 Realm이 RoomDB보다 사용이 간편해 Realm을 사용한다고 했는데, 그 중 가장 크게 작용했던 RoomDB의 단점이 Main Thread에서는 사용이 불가능하다는 점이었다.
이전 포스트 👉 Room DB 사용하기
그런데 회사 프로젝트 진행을 하던 중 LiveData를 사용하면 메인 스레드에서도 데이터를 읽어올 수 있다는 글을 보게 되었다.
LiveData 자체가 비동기적으로 동작하기 때문에 Main Thread에서도 에러가 발생하지 않는다는 것이 핵심이었다.
이를 토대로 위 포스트의 코드를 리팩토링 해본다면
@Dao
interface RecipeDao {
...
@Query("SELECT * FROM recipe")
fun getAll(): LiveData<List<Recipe>>
...
}
위처럼 SELECT문을 LiveData 형태로 받도록 수정해준다.
이제 getAll() 함수의 반환 자료형은 LiveData가 되었기 때문에 Observe가 가능하다!
이를 사용하는 측에서 observe를 해주면 된다.
recipeDB?.recipeDao()?.getAll()?.observe(lifecycleOwner) {
mAdapter = RecipeAdapter(it)
recipeRecyclerView.adapter = mAdapter
recipeRecyclerView.layoutManager = LinearLayoutManager(this)
}
방식으로 라이브데이터의 값을 옵저빙할 수 있게 된다.
이 방식의 장점은 기존의 ViewModel에서 LiveData로 모델을 관리하면서 값의 변화에 따라 뷰를 자동으로 갱신시키는 방식을 그대로 적용할 수가 있다는 것이다!
기존 코드에는 아래처럼 마지막에 갱신된 값을 다시 가져와 뷰를 갱신했다.
Thread {
val newRecipe = Recipe(
null,
itemSpinner.selectedItem.toString(),
converted,
convert)
recipeDB?.recipeDao()?.insert(newRecipe)
mAdapter.recipes = recipeDB?.recipeDao()?.getAll()!!
}.start()
하지만 이제 뷰를 직접 갱신할 필요가 없다.
lifecycleScope.launch {
val newRecipe = Recipe(
null,
itemSpinner.selectedItem.toString(),
converted,
convert)
recipeDB?.recipeDao()?.insert(newRecipe)
}
위 코드로 DB에 insert를 수행해주면 LiveData에 적용돼있는 Observer가 작동해서 자동으로 뷰를 갱신하게 된다.
RoomDB에 Coroutine을 곁들여 사용하니 정보 흐름이 굉장히 편해지는 느낌이었다.
'Programming > Android_Kotlin' 카테고리의 다른 글
SavedInstanceState와 ViewModel (0) | 2023.08.05 |
---|---|
lifecycleOwner와 viewLifecycleOwner의 차이 (0) | 2023.07.31 |
Android Custom View 만들기 (1) | 2021.11.13 |
Array의 toList()와 asList() (0) | 2021.10.17 |
RecyclerView 첫 번째, 마지막 아이템 간격 주기 (0) | 2021.10.17 |