随心所欲地进入房间

问题描述 投票:0回答:1

我正在开发一个简单的 Android 应用程序用于教育目的。该应用程序使用 Room、Flow、Repository 和 ViewModel 在本地管理产品数据。

我正在 getProductById(id:Int) 方法内收集 ViewModel 中的流。

问题是:当使用 getProductById(id:Int) 检索产品时,一切正常。 但是当我删除这个产品时,出现错误:*“java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法”* 我猜流程仍在收集有关已删除产品的数据。并且,由于它不存在,因此会发生此错误。如何修复它?可以停流吗? 谢谢

ProductDAO使用Flow来获取数据:

@Dao
interface ProductDAO {
    @Insert
    suspend fun insert(productEntity: ProductEntity)


    @Query("SELECT * FROM productentity ORDER BY name")
    fun getAll(): Flow<List<ProductEntity>>

    @Query("SELECT * FROM productEntity WHERE id=:id")
     fun getProductById(id: Int): Flow<ProductEntity>


}

产品存储库

class ProductRepository (private val productDAO: ProductDAO) {

    suspend fun insert(product: ProductEntity){
        contatoDAO.insert(product)
    }

    fun getAll(): Flow<List<Product>> {
        return productDAO.getAll().map{list->list.map{it.toDoamin()}}
    }

    fun getProductById(id: Int): Flow<Product>{
       return productDAO.getProductById(id).map{it.toDoamin()}

    }
}

在我的 ViewModel 中我收集 Flow int getProductById() 方法


sealed class DetailProductState {
    data object UpdateSuccess : DetalheState()
    data object DeleteSuccess : DetalheState()
    data class GetByIdSuccess(val p: Product) : DetailProductState()
    data object ShowLoading : DetalheState()

}


 class ProductViewModel(private val repository: ProductRepository) : ViewModel(){

    
     private val _stateList = MutableStateFlow<DetailProductState>(DetailProductState.ShowLoading)
     val stateList = _stateList.asStateFlow()

     
     fun getProductById(id: Int) {
         viewModelScope.launch {
             repository.getProductById(id).collect{result->

                 _stateList.value=  DetailProductState.GetByIdSuccess(result)

             }

         }
}

最后,在我的片段中

 viewLifecycleOwner.lifecycleScope.launch{
            viewModel.stateList.collect {
                when (it) {
                    DetailProductState.DeleteSuccess -> {
                        Snackbar.make(
                            binding.root,
                            "Removed",
                            Snackbar.LENGTH_SHORT
                        ).show()
                        findNavController().popBackStack()
                    }

                    is DetailProductState.GetByIdSuccess -> {
                        fillFields(it.p)
                    }

                    DetailProductState.ShowLoading -> {}
                    DetailProductState.UpdateSuccess -> {
                        Snackbar.make(
                            binding.root,
                            "Updated",
                            Snackbar.LENGTH_SHORT
                        ).show()
                        findNavController().popBackStack()
                    }
                }
            }
        }

我非常感谢您的帮助

kotlin android-room viewmodel kotlin-flow
1个回答
0
投票

每次数据库发生更改时,流程都会发出,并在查询没有结果时发出 null。因此将其定义为返回类型

Flow<ProductEntity?>
以防止其抛出NullPointerException。您可以选择如何响应收集器中的空值,或者在收集之前通过在流程上调用
filterNotNull()
来忽略它们。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.