首页 > 解决方案 > 如何在android中使用没有LiveData的房间和数据库?

问题描述

我是新来的房间,我想为我的应用程序设置一个数据库。我浏览了 developer.android.com 上的纪录片寻找房间。我写了一个使用 LiveData 的小应用程序,它运行良好。每次数据库更改时,底层数据模型也会更改。

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

这将是第一个猜测:

dao.getAllItems();

据我所知,查询不应该在主线程上。所以我必须把它放在一个 asyncTask 中:

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;
        }
    }
}

这让我想到了下一个问题。如果我同时触发两个或多个查询,我需要一种机制来确保所有 asyncTask 都像 onFinishedAllLoadingListener 一样完成。做这个的最好方式是什么?或者有没有更简单的方法来解决我的问题,而无需将每个查询包装在单独的 asyncTask 中?

标签: javaandroiddatabase

解决方案


如何在不使用 LiveData 概念的情况下从数据库中检索数据?

不要LiveData用作 DAO 方法的返回类型。

据我所知,查询不应该在主线程上。所以我必须把它放在 asyncTask

使用Kotlin 协程或 RxJava比使用. 考虑到此代码似乎位于存储库中并且与 UI 无关,即使是普通线程或单线程也会更好。LiveDataAsyncTaskThreadExecutor

特别是,任何时候你AsyncTask只使用 with ,与简单的线程相比,一doInBackground()开始就不需要使用。AsyncTask使用的唯一原因AsyncTask是因为您需要onPostExecute()在主应用程序线程上做一些工作。

而且,由于AsyncTask被认为是过时的,我真的鼓励你使用别的东西。Room 内置了对LiveData、Kotlin 协程和 RxJava 的支持。

如果我同时触发两个或多个查询,我需要一种机制来确保所有 asyncTask 都像 onFinishedAllLoadingListener 一样完成。做这个的最好方式是什么?

在您的情况下,只需将它们放在一个线程中即可。无论如何,您的代码不会同时有两个或更多查询,因为AsyncTask默认情况下使用单个后台线程。

在其他可能的解决方案方面:

  • 使用 Kotlin 协程,可能async()并且await()是最简单的选择

  • 使用 RxJava,正如 EpicPandaForce 建议的那样,使用zip()运算符

  • 使用LiveData,使用提供运算符的库zip(),或创建自己的


推荐阅读