Должен ли я использовать @DatabaseView в комнате с LiveData? - PullRequest
0 голосов
/ 21 июня 2019

Это работает, если запустить запрос через основной поток.Если я пытаюсь получить DatabaseView с POJO Livedata, выдается ошибка

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

@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
)

Мой Dao

interface FavouriteDao {
@Query("SELECT * from AllFavourites")
fun getFavorites(): LiveData<List<AllFavourites>>

@Insert
fun insertFav(favourite: Favourite)
}

Мой репозиторий

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
}
}

Ошибка при вызове этого наблюдения в моем фрагменте

viewModel.favourites.observe(this, androidx.lifecycle.Observer { favorites ->
        favorites?.let {
            print("FAVORITE SIZE ${favorites.size}")
        }
    })

Расскажите, как использовать DatabaseView с LiveData или котлин сопрограммы с этим шаблоном MVVM.

Мне нужно напечатать этот ИЗБРАННЫЙ РАЗМЕР из моего фрагмента через фоновый поток, а не из потока пользовательского интерфейса.

1 Ответ

1 голос
/ 22 июня 2019

onCreateView() можно вызывать несколько раз для одного и того же экземпляра фрагмента (так как представление разрушается, когда фрагмент помещается в задний стек, но сам экземпляр фрагмента сохраняется).

Вы должны всегда использовать viewLifecycleOwner вместо this при использовании observe() в onCreateView(), поскольку это гарантирует, что предыдущий наблюдатель (привязан к последнему времени onCreateView() был вызван) правильно вычищен:

viewModel.favourites.observe(viewLifecycleOwner, androidx.lifecycle.Observer { favorites ->
    favorites?.let {
        print("FAVORITE SIZE ${favorites.size}")
    }
})
...