【问题标题】:Selecting Data from Room without observing从房间中选择数据而不观察
【发布时间】:2020-05-10 23:52:18
【问题描述】:

我需要从表中选择数据,对其进行操作,然后将其插入到另一个表中。这只发生在当天第一次打开应用程序并且不会在 UI 中使用时。我不想使用 LiveData,因为它不需要被观察,但是当我研究如何做到这一点时,大多数人都说我应该使用 LiveData。我尝试过使用 AsyncTask,但出现错误“无法访问主线程上的数据库,因为它可能......”。 这是我的 AsyncTask 的代码

 public class getAllClothesArrayAsyncTask extends AsyncTask<ArrayList<ClothingItem>, Void, ArrayList<ClothingItem>[]> {

        private ClothingDao mAsyncDao;
        getAllClothesArrayAsyncTask(ClothingDao dao) { mAsyncDao = dao;}


        @Override
        protected ArrayList<ClothingItem>[] doInBackground(ArrayList<ClothingItem>... arrayLists) {

            List<ClothingItem> clothingList  = mAsyncDao.getAllClothesArray();
            ArrayList<ClothingItem> arrayList = new ArrayList<>(clothingList);
            return arrayLists;
        }
    }

这就是我在我的活动中调用它的方式

        mClothingViewModel = new ViewModelProvider(this).get(ClothingViewModel.class);
        clothingItemArray = mClothingViewModel.getClothesArray();

在这种情况下,最佳做法是什么?

【问题讨论】:

    标签: java android-studio android-asynctask android-room android-livedata


    【解决方案1】:

    简要总结

    1. Room 确实不允许在主线程上执行任何操作(查询|插入|更新|删除)。您可以在 RoomDatabaseBuilder 上关闭此控件,但最好不要。
    2. 如果您不关心 UI,至少可以将您的 ROOM 式代码(可运行)放到线程、执行程序、异步任务之一(但去年已弃用)...我已经放以下示例
    3. 我认为这种对 DB 的一次性操作的最佳实践是协程(适用于在项目中使用 Kotlin 的人)和 RxJava(适用于使用 Java 的人,Single|Maybe 作为返回类型)。它们提供了更多可能性,但您应该花时间了解这些机制的意义。
    4. 观察 Room 的数据流有 LiveData、Coroutines Flow、RxJava (Flowable)。

    在启用 lambda 的情况下使用线程切换的几个示例(如果您出于某种目的不想学习更高级的东西)

    • 只是一个线程

      new Thread(() -> { List<ClothingItem> clothingList = mAsyncDao.getAllClothesArray(); // ... next operations });

    • 执行者

      Executors.newSingleThreadExecutor().submit(() -> { List<ClothingItem> clothingList = mAsyncDao.getAllClothesArray(); // ... next operations });

    • 异步任务

      AsyncTask.execute(() -> { List<ClothingItem> clothingList = mAsyncDao.getAllClothesArray(); // ... next operations });

    如果你使用存储库模式,你可以把所有这些线程切换放在那里

    Another useful link 了解 AsyncTask 弃用后的生活

    【讨论】:

    • 谢谢!在我意识到我的代码的不同部分存在问题后,我最终使用了 AsyncTask。我一定会查看 AsyncTask 弃用链接。
    • @sergiy tikhonov 我有一个类似的用例,试图将 AsyncTasks 转换为 ExecutorService 以从 Room 数据库返回一个列表。其他答案建议使用 Callable 和 Future 返回值。希望您对这种方法的想法与您简单且可能有效的方法相比。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多