【问题标题】:Updating LiveData + Room in inactive model在非活动模型中更新 LiveData + Room
【发布时间】:2021-01-23 22:33:21
【问题描述】:

我正在尝试观察另一个片段对 DB 的更改。

我有一个 fragment A(包含一个带有项目的 recyclerView)和一个 ViewModel,它具有来自 LiveData 属性房间数据库。

像这样: val allItems: LiveData<List <Item>> = repo.getAll()

如果我从片段 A 打开一个新片段(我们称之为 B)并在那里执行repo.insert(item),我希望 LiveData 的观察者在返回片段 A 时触发allItems。但这不会发生。

如何才能很好地解决它?

当然我每次打开Fragment A都可以得到onViewCreated()中的数据,但我相信一定有更好的办法。

class CharactersViewModel : BaseViewModel() {
    private val db get() = AppDatabase.getDB(MyApplication.application)

    private val repo = CharacterRepository(viewModelScope, db.characterDao())

    val characters: LiveData<List<Character>> = repo.getAll()
}
class CharacterRepository(
    private val scope: CoroutineScope,
    private val dao: CharacterDao
) {
    fun getAll() = dao.getAll()

    fun getById(itemId: Int) = dao.getById(itemId)

    fun insert(item: Character) = scope.launch {
        dao.insert(item)
    }

    fun update(item: Character) = scope.launch {
        dao.update(item)
    }

    fun delete(item: Character) = scope.launch {
        dao.delete(item)
    }
}
@Dao
interface CharacterDao {
    fun getAll(): LiveData<List<Character>>

    fun getById(itemId: Int) : LiveData<Character>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(item: Character)

    @Update(onConflict = OnConflictStrategy.REPLACE)
    suspend fun update(item: Character)

    @Delete
    suspend fun delete(item: Character)
}

注意:看起来这是因为 Fragment A 的 ViewModel 当前处于非活动状态。并且问题不是由于 viewLifecycleOwner 引起的,因为 observeForever 也没有收到通知。

更新:刚刚发现问题,附上答案。

【问题讨论】:

  • 请分享您的代码

标签: android android-room android-livedata android-viewmodel


【解决方案1】:

获取数据库实例时有。

fun getDB(appContext: Context) = Room.databaseBuilder(
    appContext,
    AppDatabase::class.java, DB_NAME
).build()

我通过将其设置为单例解决了这个问题,所以现在它返回了相同的数据库实例。

companion object {
    @Volatile
    private var INSTANCE: AppDatabase? = null

    @Synchronized
    fun getDB(context: Context): AppDatabase {
        // if the INSTANCE is not null, then return it, otherwise create the database
        return INSTANCE ?: run {
            val instance = Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java,
                DB_NAME
            ).build()
            INSTANCE = instance

            instance
        }
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    相关资源
    最近更新 更多