如何使用 Android Room 从数据库中获取一行? [复制]

Posted

技术标签:

【中文标题】如何使用 Android Room 从数据库中获取一行? [复制]【英文标题】:How to get a row from Database using Android Room? [duplicate] 【发布时间】:2021-01-31 07:43:15 【问题描述】:

一切正常(使用 AsyncTask 插入、更新、删除),但通过 id 获取单行不是...

主要问题是有两个Activity。

    RecyclerView 详情页

单击 RecyclerView 列表项后,我想通过 id 从数据库中获取一项。 如果我使用 LiveData 获取它,我无法将它与 UI 线程中的变量同步。

如何从数据库中获取单行?

在我拥有的 DAO 中:

@Query("SELECT * FROM codes WHERE id = :id")
Code getCodeById(int id);

在存储库中:

public Code retrieveCode(int id)
    return myDatabase.getCodeDao().getCodeById(id);

如果我写在主线程中

selectedCode = mCodeRepository.retrieveCode(codeId);

它给出了一个错误:

 Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

我应该使用 AsyncTask,但如何使用?

【问题讨论】:

“我应该使用 AsyncTask”——不。 “如何从数据库中获取单行?” -- 你已经有了代码。所有数据库操作都需要在后台线程上执行。对于 Java 中的查询,典型的方法是让 DAO 返回 LiveData 或 RxJava 类型(例如,SingleObservable)。 “如果我使用 LiveData 获得它,我无法将它与 UI 线程中的变量同步”——您可能想问一个单独的问题,您可以在其中提供 minimal reproducible example 显示您为此尝试过的内容。 我这里有一个小例子:***.com/questions/64396258/… 【参考方案1】:

您可以采取一些措施来解决此问题。在这种情况下,您使用的是 java。 那么,首先为什么 android 要求你不要调用 UI 线程? 在 android 中,每当您启动一个应用程序时,它都会与一个进程相关联,并且它将在主线程上运行,即 UI 线程。 默认情况下,所有操作都在 ui 线程上运行。 并且主要所有涉及 UI 实例的操作都应该在 UI 线程上运行。 现在,无论何时调用 API 或调用数据库来检索数据,都可能需要一些时间。因此,如果您在 UI 线程上运行此操作,那么可能发生的情况是它将阻止所有操作,因为一个繁重的加载任务正在进行中,这就是为什么它可能会崩溃或会给您带来无法在主线程上运行它的错误。

要解决这个问题,您可以使用

App.db = Room.databaseBuilder(this, AppDb::class.java,"Your DB Name")
                     .allowMainThreadQueries()
                     .build()

它允许你调用主线程。这是最简单直接的。

或者您可以使用 asyncTask 方法。

【讨论】:

“这是最简单直接的”——它也非常糟糕。请不要在主应用程序线程上进行磁盘 I/O。 “您可以使用 asyncTask 方法”——AsyncTask 已弃用。 是的 AsyncTask 已被弃用,但我认为对于初学者来说,如果他们首先学习和使用 asynctask 然后再转向其他方法会很好。@CommonsWare

以上是关于如何使用 Android Room 从数据库中获取一行? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

使用 Android Room 从 Junction Table 获取数据

如何从 Room 数据库中获取 SQLite 数据库实例引用?

如何从Android Room中的多个数据库中进行选择(如何附加数据库)

Android Room - 使用自动生成获取新插入行的 id - MVVM 版本

Android Room:使用 Room 插入关系实体

Android Room - 带有附加字段的多对多关系