Android 使用Kotlin中的视图模型观察房间中的数据

Android 使用Kotlin中的视图模型观察房间中的数据,android,viewmodel,android-room,android-livedata,android-jetpack,Android,Viewmodel,Android Room,Android Livedata,Android Jetpack,我正在创建一个社交媒体应用程序,并遵循MVVM模式 我被困在观察数据库中的数据。据我所知,Dao方法必须在后台thread上执行。但是我无法从Repository类实现viewmodel。我将粘贴代码,有人能给我一些帮助吗 Dao @Dao interface FeedDao{ //Post feed item @Insert(onConflict = OnConflictStrategy.IGNORE) fun insert(feed:Feed):Long //Update feed it

我正在创建一个社交媒体应用程序,并遵循
MVVM
模式 我被困在
观察数据库中的数据。据我所知,
Dao
方法必须在后台
thread
上执行。但是我无法从
Repository
类实现
viewmodel
。我将粘贴代码,有人能给我一些帮助吗

Dao

@Dao
interface FeedDao{

//Post feed item
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(feed:Feed):Long

//Update feed item
@Update(onConflict = OnConflictStrategy.IGNORE)
fun update(feed: Feed):Int

//Get feed from user friend's
@Query("SELECT * from feed")
fun getAllFeed():LiveData<List<Feed>>
}
@Dao
接口FeedDao{
//后期提要项目
@插入(onConflict=OnConflictStrategy.IGNORE)
趣味插页(提要:提要):长
//更新提要项
@更新(onConflict=OnConflictStrategy.IGNORE)
趣味更新(提要:提要):Int
//从用户朋友的
@查询(“从提要中选择*)
fun getAllFeed():LiveData
}
存储库

class FeedRepository private constructor(private val feedDao: FeedDao) {

companion object {
    @Volatile private var instance:FeedRepository? = null
    private val apiClient = ApiClient.getApiClient().create(UserClient::class.java)
    fun getInstance(feedDao: FeedDao)= instance?: synchronized(this){
      instance ?: FeedRepository(feedDao).also { instance=it }
     }
}


private fun getFeedResponse() {

    //TODO:Check to change parameter values after adding Paging Functionality
    val call: Call<List<Feed>> = apiClient.getFeed(20, 0)
    call.enqueue(object :Callback<List<Feed>>{
        override fun onFailure(call: Call<List<Feed>>?, t: Throwable?) {
            Log.e("FeedRepository","Feed Callback Failure")
            Timber.d(t?.message)
        }

        override fun onResponse(call: Call<List<Feed>>?, response: Response<List<Feed>>?) {
            if(response!!.isSuccessful){
                Timber.i("Successful Response -> Adding to DB")
                addResponseTODB(response.body()!!)
            }else{
                when(response.code()){
                    400 -> Timber.d("Not Found 400")
                    500 -> Timber.d("Not logged in or Server broken")
                }

            }

        }
    })
}

private fun addResponseTODB(items:List<Feed>){
    Timber.d("Response --> DB Started")
    object :  AsyncTask<List<Feed>,Void,Boolean>(){
        override fun doInBackground(vararg params: List<Feed>?): Boolean {
            var needsUpdate:Boolean = false
            for(item in params[0]!!.iterator()){
                var inserted = feedDao.insert(item)
                if(inserted.equals(-1)){
                    var updated = feedDao.update(item)
                    if(updated > 0){
                        needsUpdate = true
                    }
                }else{
                    needsUpdate = true
                }
            }
            return needsUpdate
        }

        override fun onPostExecute(result: Boolean?) {
            if (result!!){
                loadFromDB()
            }
        }

    }.execute(items)
}


private fun loadFromDB(){
    Timber.d("loadFromDB")

    object :AsyncTask<Void,Void,LiveData<List<Feed>>>(){
        override fun doInBackground(vararg params: Void?): LiveData<List<Feed>>? {
            return feedDao.getAllFeed()
        }

        override fun onPostExecute(result: LiveData<List<Feed>>?) {

        }
    }.execute()
}


public fun fetchFeed(){
    Timber.d("fetchFeed")
    loadFromDB()
    getFeedResponse()
}

}
类FeedRepository私有构造函数(私有val feedDao:feedDao){
伴星{
@易失性私有变量实例:FeedRepository?=null
private val apiClient=apiClient.getApiClient().create(UserClient::class.java)
fun getInstance(feedDao:feedDao)=实例?:已同步(此){
实例?:FeedRepository(feedDao)。也是{instance=it}
}
}
私人娱乐getFeedResponse(){
//TODO:选中可在添加分页功能后更改参数值
val call:call=apiClient.getFeed(20,0)
排队(对象:Callback{
覆盖失效时的乐趣(调用:调用?、t:可丢弃?){
Log.e(“FeedRepository”,“Feed回调失败”)
Timber.d(t?.message)
}
覆盖fun onResponse(调用:调用?,响应:响应?){
如果(响应!!.isSuccessful){
Timber.i(“成功响应->添加到数据库”)
addResponseTODB(response.body()!!)
}否则{
当(response.code()){
400->Timber.d(“未找到400”)
500->Timber.d(“未登录或服务器损坏”)
}
}
}
})
}
私人娱乐添加响应数据库(项目:列表){
Timber.d(“响应-->数据库已启动”)
对象:AsyncTask(){
重写fun doInBackground(vararg参数:List?):布尔值{
var needsUpdate:Boolean=false
for(参数[0]中的项!!.iterator()){
插入变量=feedDao.insert(项目)
如果(插入。等于(-1)){
var updated=feedDao.update(项目)
如果(更新>0){
needsUpdate=true
}
}否则{
needsUpdate=true
}
}
返回日期
}
重写onPostExecute(结果:布尔值?){
如果(结果!!){
loadFromDB()
}
}
}.执行(项目)
}
private fun loadFromDB(){
d.木材(“荷载自DB”)
对象:AsyncTask(){
覆盖fun doInBackground(vararg参数:Void?):LiveData{
返回feedDao.getAllFeed()
}
重写onPostExecute(结果:LiveData?){
}
}.execute()
}
公共信息源(){
木材d(“FETCHTFEED”)
loadFromDB()
getFeedResponse()
}
}
视图模型

class FeedViewModel private constructor(private val 
feedDao:FeedDao):ViewModel(){
// TODO: Implement the ViewModel

private val feedRepository= FeedRepository.getInstance(feedDao)
public val feed = MediatorLiveData<List<Feed>>()
val value = MutableLiveData<Int>()
init {
        feed.addSource(feed,feed::setValue)
}

companion object {
    private const val NO_FEED = -1
}

fun getFeedLD() = feed

}
class FeedViewModel私有构造函数(私有值
feedDao:feedDao):ViewModel(){
//TODO:实现ViewModel
private val feedRepository=feedRepository.getInstance(feedDao)
public val feed=MediatorLiveData()
val value=MutableLiveData()
初始化{
addSource(提要,提要::setValue)
}
伴星{
私有const val NO_FEED=-1
}
fun getFeedLD()=feed
}

首先,您不需要在
数据库中逐个插入所有
Feed
对象。您可以在
FeedDao
中创建一个方法,插入
List

@Insert(onConflict=OnConflictStrategy.IGNORE)
趣味插页(提要:列表):长
然后,无需在
onPostExecute()
方法内调用
loadFromDB()
,因为您的
fun getAllFeed():LiveData()
@FeedDao
中的
方法返回
LiveData
,您可以向其中添加
Observer
,每次数据库中的数据发生更改时,都会触发
Observer

对于您的网络/数据库请求,您始终可以使用
NetworkBoundResource


希望我能帮上忙:)

你能检查一下这个链接吗。我刚用谷歌搜索了你的问题,发现了这个。我认为这个链接可以帮助你实现ViewModel&Repository类。
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(feed: List<Feed>):Long