Android 开发 - Room、LiveData、Repository 和 ViewModel

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

我正在使用架构组件学习 Android 开发。我对它们的正确使用有一些疑问。 这是我的代码,它是在本地保存数据的简单应用程序。

产品实体

@Entity
data class ProductEntity (
 @PrimaryKey(autoGenerate = true)
 val id: Int,
 val name:String,
)

产品DAO

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


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

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


}

产品存储库


class ProductRepository (private val productDAO: ProductDAO) {

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

    fun getAll(): LiveData<List<ProductEntity>> {
        return productDAO.getAll()
    }

    fun getProductById(id: Int): LiveData<ProductEntity>{
       return productDAO.getProductById(id)

    }
}

产品视图模型


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

    val allProducts:LiveData<List<ProductEntity>> = repository.getAll()
    lateinit var product : LiveData<ProductEntity>
 

    fun insert(productEntity: ProductEntity) = viewModelScope.launch(Dispatchers.IO){
        repository.insert(productEntity)
    }

   

    fun getProductById(id: Int) {
        viewModelScope.launch {
            product = repository.getProductById(id)
        }


    }

     companion object {

         fun productViewModelFactory() : ViewModelProvider.Factory =
             object : ViewModelProvider.Factory {
                 override fun <T : ViewModel> create(
                     modelClass: Class<T>,
                     extras: CreationExtras
                 ): T {
                     val application = checkNotNull(
                         extras[APPLICATION_KEY]
                     )
                     return ProductViewModel(
                         (application as Application).repository
                     ) as T
                 }
             }
     }



}

最后,在我的片段中:

class MyFragment : Fragment() {
  lateinit var product: ProductEntity

  val viewModel : ProductViewModel by viewModels { ProductViewModel.productViewModelFactory() }

   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

           viewModel.allProducts.observe(viewLifecycleOwner) { list ->
            list?.let {
                myAdapter.updateList(list)
            }
          }
    

       val p = ProductEntity(1,'Smartphone')
       viewmodel.insert(p)


       viewModel.getProductById(1)

       
       viewModel.product.observe(viewLifecycleOwner) { result ->
            result?.let {
                product = result
            }
        }

       viewModel.delete(product)
   }

}

问题:

  1. 在仅管理本地数据的应用程序中使用 LiveData 有意义吗? (参见 ProductDAO)

  2. 假设问题1的答案是“是”,即使是有趣的 getProductById(id: Int): LiveData 也应该返回一个 LiveData 吗?

  3. Android 网站表示 LiveData 对象不应在存储库中使用(参见此处)。但是,我在许多示例存储库中使用 LiveData,作为我自己的代码(ProductRepository)

  4. 使用 LiveData 还是 Flow 更好?

  5. 在我的片段中,当我尝试使用 viewModel.delete(product) 删除产品(通过观察者检索)时,应用程序崩溃。错误消息显示“NullPointerException:指定为非 null 的参数在 ProductRepository.getProductById 中为 null”。为什么会这样?我猜想观察者仍然存在,然后使用该 ID 查询数据库会返回 null,因为该对象不再存在。但我不知道如何解决它。有什么帮助吗?

谢谢!

android android-room android-livedata android-viewmodel
1个回答
0
投票

1- 不要在 Dao 中使用 LiveData。仅退回您的产品。无需更多……也许流动;流已经使用协程。支持异步流...

2-

3-LiveData 旨在根据 UI 组件的生命周期更新它们。另一方面,存储库通常独立于 UI 组件运行,并且通常具有较长的生命周期。将 LiveData 存储在存储库中可能会导致生命周期管理问题。

4- Flow 在某个地方更好,livedata 在某个地方更好...对我来说,Livedata 的 Flow 好一点:)

5-等待结果...你可以像这样修复它。

   viewModel.product.observe(viewLifecycleOwner) { result ->
        result?.let {
            product = result
            viewModel.delete(product)
        }
    }

花时间观察。如果你不想崩溃,你会检查产品是否为空。

    if(product != null) {
     viewModel.delete(product) 
}

 @PrimaryKey(autoGenerate = true)
 val id: Int,

Id 是自动生成的!首次打开的 App id 1 被创建并删除。再次打开应用程序;产品采用新 ID。 2、3、4...

val p = ProductEntity(1,'Smartphone') 

1 为无效元素。

© www.soinside.com 2019 - 2024. All rights reserved.