Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在kotlin协程中使用room从服务器获取数据后,如何将数据保存到数据库?_Android_Database_Android Room_Kotlin Coroutines - Fatal编程技术网

Android 在kotlin协程中使用room从服务器获取数据后,如何将数据保存到数据库?

Android 在kotlin协程中使用room从服务器获取数据后,如何将数据保存到数据库?,android,database,android-room,kotlin-coroutines,Android,Database,Android Room,Kotlin Coroutines,我正在开发新闻应用程序,我想在使用room从服务器获取数据后将数据保存到数据库,但我很困惑,我已经遵循了教程,但它们的逻辑不同,我如何正确保存数据,以便在从服务器获取数据后将数据保存到数据库 在我的SportNewsDatabase.kt下面 @Database(entities = [Article::class], version = 1, exportSchema = false) abstract class SportNewsDatabase : RoomDatabase() {

我正在开发新闻应用程序,我想在使用room从服务器获取数据后将数据保存到数据库,但我很困惑,我已经遵循了教程,但它们的逻辑不同,我如何正确保存数据,以便在从服务器获取数据后将数据保存到数据库

在我的SportNewsDatabase.kt下面

@Database(entities = [Article::class], version = 1, exportSchema = false)
abstract class SportNewsDatabase : RoomDatabase() {

    abstract fun sportNewsDao(): SportNewsDao

    companion object {
        private var instance: SportNewsDatabase? = null
        fun getInstance( context: Context): SportNewsDatabase? {
            if (instance == null) {
                synchronized(SportNewsDatabase::class.java) {
                    instance = Room.databaseBuilder(context.applicationContext, SportNewsDatabase::class.java, "article_database")
                        .fallbackToDestructiveMigration()
                        .build()
                }
            }
            return instance
        }
    }


}
下面是SportNewsDao.kt

@刀 接口SportNewsDao{

@Query("SELECT * FROM  article")
fun getAllData(): LiveData<List<Article>>

@Insert
 suspend fun addAll(article: List<Article>)


@Update
 suspend fun updateArticle(article: Article)

@Delete
 suspend fun deleteArticle(article: Article)
@Query(“从文章中选择*)
fun getAllData():LiveData
@插入
暂停乐趣添加(文章:列表)
@更新
暂停乐趣更新文章(文章:文章)
@删除
第条(第条:第条)
}

在我的存储库类下面
接口新闻存储库{
//Suspend用于等待来自Deferred的结果
suspend fun getNewsList():UseCaseResult
var sportNewsDao:sportNewsDao
}
趣味插页(文章:列表){
val插入物
}
@抑制(“未选中的_CAST”)
类NewsRepositoryImpl(私有val-SportNewsAPI:SportNewsInterface):新闻存储库{
重写getNewsList():UseCaseResult{
回击{
val result=sportsNewsApi.getNewsAsync().body()!!.articles
UseCaseResult.Success(结果)
}捕获(例如:异常){
UseCaseResult.Error(ex)
}
}
}
在MainViewModel.kt下面,我正在使用Kotlin协程

@Suppress("UNCHECKED_CAST")
class MainViewModel(val newsRepository: NewsRepository) : ViewModel(), CoroutineScope {
    // Coroutine's background job
    val job = Job()
    // Define default thread for Coroutine as Main and add job
    override val coroutineContext: CoroutineContext = Dispatchers.Main + job

    val showLoading = MutableLiveData<Boolean>()
    val sportList = MutableLiveData<List<Article>>()
    val showError = SingleLiveEvent<String>()

    fun loadNews() {
        // Show progressBar during the operation on the MAIN (default) thread
        showLoading.value = true
        // launch the Coroutine
        launch {
            // Switching from MAIN to IO thread for API operation
            // Update our data list with the new one from API
            val result = withContext(Dispatchers.IO) {
                newsRepository?.getNewsList()
            }
            // Hide progressBar once the operation is done on the MAIN (default) thread
            showLoading.value = false
            when (result) {

                is UseCaseResult.Success<*> -> {
                    sportList.value = result.data as List<Article>
                }
                is Error -> showError.value = result.message
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        // Clear our job when the linked activity is destroyed to avoid memory leaks
        job.cancel()
    }
}
@Suppress(“未选中的\u CAST”)
类MainViewModel(val newsRepository:newsRepository):ViewModel(),CoroutineScope{
//Coroutine的背景工作
val job=job()
//将协同程序的默认线程定义为主线程并添加作业
override val coroutineContext:coroutineContext=Dispatchers.Main+job
val showLoading=MutableLiveData()
val sportList=MutableLiveData()
val-showError=SingleLiveEvent()
有趣的新闻{
//在主(默认)线程上的操作期间显示progressBar
showLoading.value=true
//启动协同程序
发射{
//从主线程切换到IO线程以进行API操作
//用API中的新数据更新我们的数据列表
val结果=withContext(Dispatchers.IO){
新闻存储库?.getNewsList()
}
//在主(默认)线程上完成操作后隐藏progressBar
showLoading.value=false
何时(结果){
是UseCaseResult。成功->{
sportList.value=result.data作为列表
}
is Error->BREASHROR.value=result.message
}
}
}
覆盖有趣的onCleared(){
super.onCleared()
//当链接的活动被破坏时清除我们的作业,以避免内存泄漏
作业。取消()
}
}
@sashabeliy

您好,我想我有您问题的解决方案,但我不是mvvm和协同程序方面的专家,因此如果有人有更好的解决方案,我会选择:)

对于我的应用程序,我在主线程中启动下载,只有当我得到响应时,我才使用Dispatchers.IO在房间中插入收到的数据

在视图模型中

fun下载PDV(上次更新:String):LiveData{
return repositoryPDV.downloadPDV(上次更新)
}

存储库中

fun downloadPDV(last_update : String ): LiveData<List<PDV>> {
    val mutableLiveData: MutableLiveData<List<PDV>> = MutableLiveData()
    val apiService: ApiInterface = RetrofitClient.getRetrofitClient().create(ApiInterface::class.java)

    apiService.CallListPDV(last_update)?.enqueue(object :
        Callback<List<PDV>> {
        override fun onResponse(
            call: Call<List<PDV>>,
            response: Response<List<PDV>>
        ) {
            Log.e(ContentValues.TAG, "Download PDV Success => $response")

            if (response.isSuccessful && response.body() != null) {

                mutableLiveData.setValue(response.body());

                GlobalScope.launch(Dispatchers.IO) {
                    for (pdv in response.body()!!) {
                        insertPDV(pdv)
                    }
                }
            }
        }

        override fun onFailure(call: Call<List<PDV>>, t: Throwable) {
            Log.e(ContentValues.TAG, "[Error] Download PDV Fail --> $call")
        }
    })
    return mutableLiveData
}
fun下载PDV(上次更新:String):LiveData{
val mutableLiveData:mutableLiveData=mutableLiveData()
val apiService:ApiInterface=RefundationClient.GetRefundationClient().create(ApiInterface::class.java)
apiService.CallListPDV(上次更新)?.enqueue(对象:
回拨{
覆盖响应(
呼叫:呼叫,,
答复:答复
) {
Log.e(ContentValues.TAG,“下载PDV成功=>$response”)
if(response.issusccessful&&response.body()!=null){
mutableLiveData.setValue(response.body());
GlobalScope.launch(Dispatchers.IO){
for(响应中的pdv.body()!!){
插入式pdv(pdv)
}
}
}
}
覆盖失效时的乐趣(调用:调用,t:可丢弃){
Log.e(ContentValues.TAG,“[Error]下载PDV失败-->$call”)
}
})
返回可变LiveData
}

我返回数据下载以更新UI,并通知用户下载了多少项

指定代码部分correctly@MohammadMoeinGolchin你是什么意思?现在它已经被编辑了,但它的功能还存在问题structure@MohammadMoeinGolchin关于你的问题,你有什么建议?不知道。马格德非常感谢你的回答。我已经解决了我的问题。我希望你是安全的。谢谢,同样感谢。你的解决方案是什么?
fun downloadPDV(last_update : String ): LiveData<List<PDV>> {
    val mutableLiveData: MutableLiveData<List<PDV>> = MutableLiveData()
    val apiService: ApiInterface = RetrofitClient.getRetrofitClient().create(ApiInterface::class.java)

    apiService.CallListPDV(last_update)?.enqueue(object :
        Callback<List<PDV>> {
        override fun onResponse(
            call: Call<List<PDV>>,
            response: Response<List<PDV>>
        ) {
            Log.e(ContentValues.TAG, "Download PDV Success => $response")

            if (response.isSuccessful && response.body() != null) {

                mutableLiveData.setValue(response.body());

                GlobalScope.launch(Dispatchers.IO) {
                    for (pdv in response.body()!!) {
                        insertPDV(pdv)
                    }
                }
            }
        }

        override fun onFailure(call: Call<List<PDV>>, t: Throwable) {
            Log.e(ContentValues.TAG, "[Error] Download PDV Fail --> $call")
        }
    })
    return mutableLiveData
}