【问题标题】:Livedata and ViewModel update infinite number of timesLivedata 和 ViewModel 更新无限次
【发布时间】:2021-10-10 22:04:13
【问题描述】:

当我尝试将模型更新到房间数据库时。我希望它只会更新一次,但它会更新无数次。

@Dao
interface UserDAO {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUserDAO(userModel : UserModel)

    @Update
    suspend fun updateUserDAO(userModel : UserModel)

    @Query("select * from user_table where _id =:id")
    fun readUserById(id : String) : LiveData<UserModel>

存储库

class UserRepository(private val userAPI: UserAPI, context : Context) {
    private val userDAO : UserDAO
    init {
        val userDatabase: UserRoomDatabase = UserRoomDatabase.getInstance(context)
        userDAO = userDatabase.getUserDao()
    }
    
     fun readUserByIdDAO(id : String): LiveData<UserModel> = userDAO.readUserById(id)
    suspend fun insertUserDAO(userModel : UserModel) = userDAO.insertUserDAO(userModel)
    suspend fun updateUserDAO(userModel : UserModel) = userDAO.updateUserDAO(userModel)
}

视图模型

class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
    val userModelResponse: MutableLiveData<Resource<UserModel>> = MutableLiveData()
    val listUserModelResponse: MutableLiveData<Resource<ArrayList<UserModel>>> = MutableLiveData()
  fun readUserByIdDAO(id : String) : LiveData<UserModel> = userRepository.readUserByIdDAO(id)

    fun insertUserDAO(userModel: UserModel) = viewModelScope.launch {
        userRepository.insertUserDAO(userModel)
    }
    fun updateUserDAO(userModel: UserModel) = viewModelScope.launch {
        userRepository.updateUserDAO(userModel)
    }
}

然后我在 MainActivity 中使用它

class MainActivity : AppCompatActivity() {
    private lateinit var viewModel: UserViewModel
    private lateinit var binding: ActivityMainBinding
    private lateinit var auth : FirebaseAuth
    private var userId = ""

    override fun onStart() {
        super.onStart()
        val navController = findNavController(R.id.fragmentHome)
        binding.bottomNavigationHome.setupWithNavController(navController)
        val userAPI = UserAPI.getInstance()
        val userRepository = UserRepository(userAPI,this)
        viewModel =
            ViewModelProvider(this, UserModelFactory(userRepository)).get(UserViewModel::class.java)
        auth = Firebase.auth
        userId = auth.currentUser!!.uid
        viewModel.readUserByIdDAO(userId).observe(this,{ userFromDAO ->
            userFromDAO.active = true
            viewModel.updateUserDAO(userFromDAO)
            Log.e(TAG,userFromDAO.toString())

        })

    }
override fun onStop() {
        super.onStop()
        Log.e(TAG,"Stop")
        viewModel.readUserByIdDAO(userId).observe(this,{ userFromDAO ->
            userFromDAO.active = false
            viewModel.updateUserDAO(userFromDAO)
            viewModel.updateUserAPI(userFromDAO)
        })
    }

我的问题是什么,我该如何解决?

每一天都给我们带来许多惊喜;今天,我祝大家有一个壮观的一天。祝你一切顺利

【问题讨论】:

  • 您正在从观察者更新您的数据库以设置相同的项目其读数。
  • 所以我不能在观察者中更新用户?那么我该如何解决呢?
  • userFromDAO.active = true。我想检查用户是在线还是离线。

标签: android kotlin android-room


【解决方案1】:

真正的问题是,你想做什么?如果只在 onstart 和 onstop 更新数据库,为什么需要 livedata?您在评论中说要在线或离线检查用户。你为什么把它写到数据库中?告诉我们您想要实现的目标,我们可以找到另一种解决方案..

顺便说一句,如果您想检查用户是否在线,这是我的回答:

如果您想在线或离线检查用户,为什么不直接检查 设备在线还是离线?你可以在这里看到如何做到这一点: How to check if an android device is online

上面的链接告诉你如何制作一个函数来检查你的 连接状态。如果你想自动做某事 当网络状态发生变化时,您需要运行该函数来检查 您的应用程序运行时的每次连接。那不是 有效的。如果您想自动使用工作管理器,您可以使用 检测网络变化: How to trigger work manager when wifi is connected in android?

因此,如果您知道何时要检查网络状态,请使用 第一种方法。如果要监控网络状态并自动 状态变化时做点什么,用第二种方法。

【讨论】:

  • 对不起,我想了很多。非常感谢!
【解决方案2】:

使用 if 语句,这样您就不会重复写回相同的项目

if (!userFromDAO.active) {
    userFromDAO.active = true
    viewModel.updateUserDAO(userFromDAO)
}
Log.e(TAG,userFromDAO.toString()) 

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 2020-03-17
    • 2021-11-04
    相关资源
    最近更新 更多