Its working if run query through main thread. If I try to get DatabaseView with Livedata POJO, Its throwing error
java.lang.IllegalArgumentException: Cannot add the same observer with different lifecycles
at androidx.lifecycle.LiveData.observe(LiveData.java:197)
at MyFragment.onCreateView(MyFragment.kt:45)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7058)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
DatabaseView class
@DatabaseView("SELECT ss_pack.id as id, ss_pack.title as title, ss_pack.primary_value as primaryValue FROM ss_pack JOIN favourite WHERE favourite.ss_pack_id = ss_pack.id")
data class AllFavourites(
val id: Int,
val title: String,
val primaryValue: String
)
My Dao
interface FavouriteDao {
@Query("SELECT * from AllFavourites")
fun getFavorites(): LiveData<List<AllFavourites>>
@Insert
fun insertFav(favourite: Favourite)
}
My Repository
class MyRepository(val favoriteDao: FavoriteDao, val categoryDao: CategoryDao) {
val favourites: LiveData<List<AllFavourites>> = favoriteDao.getFavorites()
val categories: LiveData<List<Category>> = categoryDao.loadAllCategories()
}
ViewModel
class MyViewModel(application: Application) : AndroidViewModel(application){
private val myRepository: MyRepository
val favourites: LiveData<List<AllFavourites>>
init {
val favoriteDao = SDatabase.getDatabase(application, viewModelScope).favoriteDao()
myRepository = myRepository(favoriteDao, categoryDao)
favourites = passwordRepository.favourites
}
}
Error throwing when I call this observe in my fragment
viewModel.favourites.observe(this, androidx.lifecycle.Observer { favorites ->
favorites?.let {
print("FAVORITE SIZE ${favorites.size}")
}
})
Tell me how to use DatabaseView with LiveData or kotlin coroutines with this MVVM Pattern.
I need to print that FAVORITE SIZE from my fragment through background thread not from UI thread.
onCreateView()
can be called multiple times for the same Fragment instance (as the view is destroyed when the Fragment is put on the back stack, but the Fragment instance itself is kept around).
You should always use viewLifecycleOwner
rather than this
when using observe()
in onCreateView()
as this ensures that the previous observer (tied to the last time onCreateView()
was called) is properly cleaned up:
viewModel.favourites.observe(viewLifecycleOwner, androidx.lifecycle.Observer { favorites ->
favorites?.let {
print("FAVORITE SIZE ${favorites.size}")
}
})