Java 如何在android中使用没有LiveData的房间和数据库?
我是新来的,我想为我的应用程序建立一个数据库。我浏览了developer.android.com上的《房间》纪录片。我写了一个使用LiveData的小应用程序,效果很好。每次数据库更改时,基础数据模型也会更改 但是对于一个新的应用程序,我不需要LiveData功能。我有一组数据存储在数据库中,不能被应用程序更改。所以它或多或少是静态的。如何在不使用LiveData概念的情况下从数据库检索数据 这是第一个猜测:Java 如何在android中使用没有LiveData的房间和数据库?,java,android,database,Java,Android,Database,我是新来的,我想为我的应用程序建立一个数据库。我浏览了developer.android.com上的《房间》纪录片。我写了一个使用LiveData的小应用程序,效果很好。每次数据库更改时,基础数据模型也会更改 但是对于一个新的应用程序,我不需要LiveData功能。我有一组数据存储在数据库中,不能被应用程序更改。所以它或多或少是静态的。如何在不使用LiveData概念的情况下从数据库检索数据 这是第一个猜测: dao.getAllItems(); 据我所知,查询不应该在主线程上。 所以我必须把
dao.getAllItems();
据我所知,查询不应该在主线程上。
所以我必须把它放在一个异步任务中:
public class Repository {
private dbDao mDao;
private List<Items> mAllItems;
public Repository(Application application) {
DB db = DB.getDatabase(application);
mDao = db.dao();
new queryAsyncTask(mDao).execute(mAllItems);
}
private static class queryAsyncTask extends AsyncTask<List<Items>, Void, Void> {
private dbDao mAsyncTaskDao;
queryAsyncTask(dbDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(List<Items>... params) {
params[0] = mAsyncTaskDao.getAllItems();
return null;
}
}
}
公共类存储库{
私营部门;
私人物品清单;
公共存储库(应用程序){
DB=DB.getDatabase(应用程序);
mDao=db.dao();
新建queryAsyncTask(mDao)。执行(mAllItems);
}
私有静态类queryAsyncTask扩展异步任务{
私有dbDao mAsyncTaskDao;
queryAsyncTask(dbDao){
mAsyncTaskDao=dao;
}
@凌驾
受保护的Void doInBackground(列表…参数){
params[0]=mAsyncTaskDao.getAllItems();
返回null;
}
}
}
这就引出了下一个问题。如果我同时启动两个或多个查询,我需要一种机制来确保所有异步任务都像onFinishedAllLoadingListener一样完成。最好的方法是什么?或者有没有更简单的方法来解决我的问题,而不必将每个查询包装在单独的异步任务中
如何在不使用LiveData概念的情况下从数据库检索数据
不要使用LiveData
作为DAO方法的返回类型
据我所知,查询不应该在主线程上。所以我必须把它放在一个异步任务中
使用LiveData
、Kotlin协同程序或RxJava比使用AsyncTask
要好得多。即使是普通的线程
或单线程执行器
也会更好,因为这些代码似乎位于存储库中,并且没有绑定到UI
特别是,任何时候只要将AsyncTask
与doInBackground()
一起使用,与简单线程相比,根本不需要使用AsyncTask
。使用AsyncTask
的唯一原因是您需要onPostExecute()
在主应用程序线程上执行一些工作
而且,由于AsyncTask
被认为是过时的,我真的鼓励您使用其他东西。Room内置了对LiveData
、Kotlin协同程序和RxJava的支持
如果我同时启动两个或多个查询,我需要一种机制来确保所有异步任务都像onFinishedAllLoadingListener一样完成。最好的方法是什么
在您的情况下,只需将它们放在一个线程中。您的代码不会同时有两个或多个查询,因为默认情况下,AsyncTask
使用单个后台线程
就其他可能的解决方案而言:
- 对于Kotlin协程,最简单的选择可能是
和async()
await()
- 对于RxJava,正如EpicPandaForce建议的那样,使用
操作符zip()
- 使用
,使用提供LiveData
zip()运算符的,或
doInBackground
中运行它们,这对您来说肯定会更容易。请注意,Void
应该是您在onPostExecute
中返回和接收的值。RxJava现在几乎是行业标准。请考虑使用您的目的(并忘记异步任务为好)。有很多这样的例子。Room内置了对和@ror的支持,我想他正在寻找Single.zip
@EpicPandaForce agree-假设获取所提到的db请求的性质,这是完全可能的。我只是不喜欢编写zip函数:)我想我需要更具体的帮助。让我们假设我们正在制作一个应用程序,该应用程序只显示使用room的sql数据库中的数据。数据库中的数据只填充一次,以后再也不会接触。因此,应用程序不会更改数据库中的任何数据。数据库由一个表和两列“id”和“word”组成。它基本上是一个单词列表。现在我们有了一个带有一个文本视图和两个按钮(“下一个”和“上一个”)的活动。当文本视图显示单词时,用户应该能够使用按钮“下一步”和“上一步”在单词列表中切换。我的想法是:使用一个LiveData类UiData保存所有单词的列表和一个变量“currentIndex”。此类的实例由ViewModel持有,并由MainActivity观察。每次我更改“currentIndex”时,都会在MainActivity中触发onChange事件。但是我怎样才能在viewModel中把单词保存到UiData中呢?@Peter:如果你只是想保存所有单词,那么最简单的解决方案就是去掉空间和数据库。只要有一个
单词资源,或者在assets/
中使用一个JSON文件即可。如果您确定要使用Room,那么让DAO使用一个返回LiveData
的方法,其中WordEntity
是表示您的单词表的@Entity
。您的viewmodel将直接询问DAO,或者询问存储库,存储库反过来询问DAO。您的UI将观察LiveData
。以使用LiveData方法在活动中实现onChange。但是sql中的数据永远不会更改,因此永远不会触发此方法。此外,我不使用RecyclerView来显示所有单词。我只有一个单词的文本视图。因此,所有处理都将在活动中进行,而实际上应该在ViewModel中进行。所以我会