Java 如何在android中使用没有LiveData的房间和数据库?

Java 如何在android中使用没有LiveData的房间和数据库?,java,android,database,Java,Android,Database,我是新来的,我想为我的应用程序建立一个数据库。我浏览了developer.android.com上的《房间》纪录片。我写了一个使用LiveData的小应用程序,效果很好。每次数据库更改时,基础数据模型也会更改 但是对于一个新的应用程序,我不需要LiveData功能。我有一组数据存储在数据库中,不能被应用程序更改。所以它或多或少是静态的。如何在不使用LiveData概念的情况下从数据库检索数据 这是第一个猜测: dao.getAllItems(); 据我所知,查询不应该在主线程上。 所以我必须把

我是新来的,我想为我的应用程序建立一个数据库。我浏览了developer.android.com上的《房间》纪录片。我写了一个使用LiveData的小应用程序,效果很好。每次数据库更改时,基础数据模型也会更改

但是对于一个新的应用程序,我不需要LiveData功能。我有一组数据存储在数据库中,不能被应用程序更改。所以它或多或少是静态的。如何在不使用LiveData概念的情况下从数据库检索数据

这是第一个猜测:

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中进行。所以我会