Android 不需要更新的单个查询的Room LiveData vs AsyncTask

Android 不需要更新的单个查询的Room LiveData vs AsyncTask,android,android-asynctask,android-room,android-livedata,Android,Android Asynctask,Android Room,Android Livedata,我正在将我们的项目转换为使用Room ORM。当我需要更新LiveData对象时,它非常有效,对于异步任务(如插入、删除等)也非常有效,因为我不需要回调。但当我需要一个需要回调的一次性查询时,我不知道该使用什么。选项是使用DAO实现调用AsyncTask进行查询,或者使用Observer调用LiveData,在第一次接收后,取消注册Observer。我建议继续使用LiveData,特别是如果您使用的是Room提供的ViewModel。ArchitectureComponents库在将所有Room

我正在将我们的项目转换为使用Room ORM。当我需要更新LiveData对象时,它非常有效,对于异步任务(如插入、删除等)也非常有效,因为我不需要回调。但当我需要一个需要回调的一次性查询时,我不知道该使用什么。选项是使用DAO实现调用AsyncTask进行查询,或者使用Observer调用LiveData,在第一次接收后,取消注册Observer。

我建议继续使用LiveData,特别是如果您使用的是Room提供的ViewModel。ArchitectureComponents库在将所有Room、LiveData和ViewModels捆绑在一起时确实做得很好,所以尽量遵守约定

我建议坚持使用LiveDataViewModels的原因如下

  • ViewModels具有生命周期意识,这意味着它们能够做出适当的响应 对片段/活动状态进行更改,否则会导致 AsyncTask检索死机活动的数据或执行工作 当活动不再存在时,可能会导致内存丢失
  • 观察数据/数据更改是视图的最佳实践(至少对于体系结构组件而言)。如果您只需要一次回调,请在收到数据后取消订阅。或者,如果您当前正在使用RxJava,请使用RxJava单
  • 如果您觉得确实需要使用AsyncTask,我建议您使用。这是一个更健壮的/支持生命周期的后台线程操作,它将缓存数据(非常类似于AsyncTask,因此实现细节不会太陌生),因此如果您旋转设备,数据将被缓存并立即可用,并且不会出现内存泄漏。Android团队也会在加载程序上检查这一点


    但我建议使用LiveData和ViewModels

    我对房间的实施也有同样的问题。至于LiveData按房间返回,我们可以在主线程上观察它,而不必在主线程上执行数据库操作。 但是对于没有LiveData的原始对象,我们不能直接获取,因为不允许在主线程上执行数据库操作。

    我已经使用LiveData列出了一系列的东西,一旦数据库更新,我就需要更新这些东西。但是对于某些操作,我只需要获取它一次,并停止观察数据库,因为我知道它不会改变

    在我的例子中,我只使用了RxJava观察了一次查询结果

    创建可观察的以从存储库中按id获取用户

    Observable.create(object : ObservableOnSubscribe<User> {
            override fun subscribe(e: ObservableEmitter<User>) {
                val user= userRepo.getUserById(currentUserId)
                e.onNext(user)
                e.onComplete()
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(GetCurrentUserByIdSubscriber())
    
    Dao

    @Query("SELECT * FROM users WHERE id= :id")
    fun getUserById(id: Int): User
    
    您可以看到我返回的是普通用户对象,而不是LiveData

    在我想观察的活动中

    private inner class GetCurrentUserByIdSubscriber : Observer<User> {
        override fun onSubscribe(d: Disposable) {}
    
        override fun onNext(t: User) {
            // update the view after getting the data from database
            user_name.text = t.name
        }
    
        override fun onComplete() {}
    
        override fun onError(e: Throwable) {}
    }
    
    私有内部类GetCurrentUserByIdSubscriber:Observer{
    覆盖订阅(d:一次性){}
    覆盖下一页(t:用户){
    //从数据库获取数据后更新视图
    user_name.text=t.name
    }
    重写fun onComplete(){}
    重写一个错误(e:Throwable){}
    }
    
    这就是我如何使用RxJava在IO线程上执行一次性数据库获取,并在从数据库获取对象后立即获取回调。
    在获得结果后,您可以调用Subscription上的unsubscribe调用return from subscribe()方法。

    Transformations方法
    distinctUntilChanged
    中有一个简单的解决方案。仅当数据发生更改时才公开新数据

    如果发生事件行为,请使用以下方法:

    private inner class GetCurrentUserByIdSubscriber : Observer<User> {
        override fun onSubscribe(d: Disposable) {}
    
        override fun onNext(t: User) {
            // update the view after getting the data from database
            user_name.text = t.name
        }
    
        override fun onComplete() {}
    
        override fun onError(e: Throwable) {}
    }