【问题标题】:Database repository comparison and/or update in Android Kotlin?Android Kotlin 中的数据库存储库比较和/或更新?
【发布时间】:2020-12-31 03:38:57
【问题描述】:

我是 android 编程新手,想尝试学习最佳实践。我正在构建的第一个应用程序是一个播客应用程序,用于显示来自 rss 提要的播客并播放它们。到目前为止,我正在工作,但我知道我可以让它工作得更好。

我正在使用具有存储库模式的房间数据库,这可能有点过头了,因为如果我只是要在启动时重新解析提要,我可能不需要在应用程序死亡期间保留播客列表。在我的存储库类中,我调用我的 FetchRSS 类在 init{ } 块中进行网络调用,该块返回 List<Podcast>

我知道我做的不对。

在我的 PodcastDao 中,我必须使用 @Insert(onConflict = OnConflictStrategy.REPLACE),因为数据库已经存在并且我收到关于重复主键 ID 的 SQL 错误 1555。从逻辑上讲,最好检查一下要添加的条目是否已经在数据库中,但我不确定如何去做。或者,不合逻辑地,在应用程序死亡时清除数据库,但是为什么还要为数据库而烦恼。理想情况下,我希望有滑动更新功能(即使 RSS 每周最多更新两次),但我不确定如何最好地做到这一点。

如果有人有任何关于改进这一点的想法,或者一本学习 android 的好书,我会全力以赴。 非常感谢所有花时间看这个的人!

PodcastDao.kt

@Dao
interface PodcastDao {

    @Query("SELECT * FROM podcast")  // get everything from the database
    fun getPodcasts(): LiveData<List<Podcast>>

    @Query("SELECT * FROM podcast WHERE id=(:id)") // get the specific podcast
    fun getPodcast(id: String): LiveData<Podcast?>

//    @Insert(onConflict = OnConflictStrategy.REPLACE)
//    fun addPodcasts(podcasts: LiveData<List<Podcast>>)
//    this causes a build error with the generated PodcastDao.java file
// logcat error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun addPodcast(podcast: Podcast)
}

PodcastRepository.kt

class PodcastRepository private constructor(context: Context) {

private lateinit var podcasts: List<Podcast>

    init {

        CoroutineScope(Dispatchers.Main).launch {

            podcasts = FetchRSS().fetchRss() // executes on Dispatchers.IO and returns parsed rss List<Podcast>

            // this seems silly to add them one at a time, especially since the list is rather large
            for (pod in podcasts) {
                addPodcast(pod)
            }
            //it seems a better choice to dump the full list into the database at once
            //however I can't figure out how to put the List<Podcast> into a LiveData<List<Podcast>> object
            //or maybe I'm misunderstanding something about LiveData<>
            //addPodcasts(podcasts)
        }
    }

    suspend fun addPodcast(podcast: Podcast){
        withContext(Dispatchers.IO){
            podcastDao.addPodcast(podcast)
        }

// this needs to receive the LiveData<List<Podcast>>, or a List<Podcast> and cram it into LiveData<>?
//    suspend fun addPodcasts(podcasts: LiveData<List<Podcast>>) {
//        withContext(Dispatchers.IO){
//            podcastDao.addPodcasts(podcasts)
//        }
//    }
    }

【问题讨论】:

    标签: android database kotlin repository-pattern android-livedata


    【解决方案1】:
    fun addPodcasts(podcasts: LiveData<List<Podcast>>)
    

    应该是

    fun addPodcasts(podcasts: <List<Podcast>>)
    

    所以,现在您可以从存储库中调用 podcastDao.addPodcasts(podcasts)(其中 podcasts 的类型为 List&lt;Podcast&gt;&gt;),而不是通过 for 循环一个一个地插入它们。

    您不能将 LiveData 插入 Room,只能将标有 @Entity 的对象插入。但是,您可以让查询返回带有这些实体列表的 LiveData。您也可以只返回一个列表。

    【讨论】:

    • 工作就像一个魅力。可以肯定的是,我删除了我的数据库并使用 addPodcasts(podcasts) 重新创建了它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2019-12-03
    • 1970-01-01
    相关资源
    最近更新 更多