如何使用Android Room从数据库获取一行数据?

huangapple go评论65阅读模式
英文:

How to get a row from Database using Android Room?

问题

一切运作正常(使用AsyncTask进行插入、更新、删除),但通过id获取单行未能正常工作...

主要问题在于有两个活动:

  1. 一个RecyclerView
  2. 详情页面

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

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

在DAO中我有:

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

在Repository中:

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,但怎么用呢?

英文:

Everything works (Insert, Update, Delete with AsyncTask) fine, but getting a single row by id not...

The main problem is that there are two Activities.

  1. A RecyclerView
  2. Details page

I would like to get one item by id from the Database after clicked on a RecyclerView list item.
If I get it with LiveData I can not synchronize it with a variable in the UI thread.

How can you get a single row from Database?

in the DAO I have:

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

in the Repository:

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

If I write it in the main thread

selectedCode = mCodeRepository.retrieveCode(codeId);

it gives an error:

 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.

Should I use AsyncTask, but how?

答案1

得分: 0

以下是翻译好的部分:

有一些事情可以解决这个问题。在这种情况下,您正在使用Java。
所以,首先,为什么Android要求您不要在UI线程上调用呢?
在Android中,每当您启动应用程序,它都会关联到一个进程,并在主线程上运行,这就是UI线程。
所有操作默认都在UI线程上运行。
主要涉及UI实例的所有操作都应在UI线程上运行。
现在,每当您调用API或调用数据库来检索数据时,可能会花费一些时间。因此,如果您在UI线程上运行此操作,可能会发生的情况是,它将阻塞所有操作,因为一个繁重的加载任务正在进行中,这可能会导致崩溃,或者会给您一个错误,即您无法在主线程上运行它。

要解决这个问题,您可以使用以下方法:

App.db = Room.databaseBuilder(this, AppDb::class.java, "您的数据库名称")
                     .allowMainThreadQueries()
                     .build()

这将允许您在主线程上调用。这是最简单直接的方法。

或者,您可以使用异步任务(AsyncTask)的方法。

英文:

There are few things you can do to resolve this issue. You are using java in this case.
So,first of all why android asking you to not call on UI thread?
In android whenever you launch an app it will get associated with one process and it will run on main thread which is UI thread.
All the operations by default run on ui thread.
And mainly all operation which involves instance of UI should run on UI Thread.
Now whenever you call an API or call database to retrieve data, it might take some time. So, if you run this operation on UI thread then what could happen is It will block all the operation as one heavy loading task is in process and thats why it could crash or can give you error that you cant run it on main thread.

to resolve this you can use

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

and it will allow you to call on mainthread. This is the simplest and straight forward.

Or You can go with asyncTask approach.

huangapple
  • 本文由 发表于 2020年10月17日 03:06:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64395017.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定