首页 > 解决方案 > 如何使用 Android Room 从数据库中获取一行?

问题描述

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

主要问题是有两个活动。

  1. 回收站视图
  2. 详情页面

单击 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,但是如何使用?

标签: javaandroidandroid-room

解决方案


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

要解决此问题,您可以使用

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

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

或者您可以使用 asyncTask 方法。


推荐阅读