首页 > 解决方案 > 带有返回值(long 或 int)的 Android Room DAO @Insert 如何工作?

问题描述

最近在学习使用DAO。据我了解,所有@Insert, @Update, 或@Query都是异步执行的。并且从纪录片中,@Insert可以返回一个long值,它是新rowId插入的项目(或者List<long>如果是多个项目)。假设我的 DAO 看起来像这样:

@Insert
long insertTransaction(Transaction transaction);

@Insert
List<Long> insertTransactions(List<Transaction> transactions);

当我在活动或片段中使用这些方法时,是否意味着我在异步任务完成后获得了长值?

<!-- language: lang-none -->

    // Do I get 0 if the insert is not complete 
    // or it will wait till the insert is complete and return long?

    long id = viewModel.insertTransaction(transaction)

如果它等待异步任务完成,它不会阻塞主线程(尤其是在插入大列表时)?如果没有,我如何检查插入是否完成?

标签: androidandroid-roomdaoandroid-mvvm

解决方案


据我了解,所有@Insert、@Update 或@Query 都是异步执行的。

默认情况下,所有@Insert、@Update 或@Query 都是同步执行的。Room 会对此发出警告,如果没有在 RoomDatabase.Builder 中显式使用方法allowMainThreadQueries,您将无法进行同步调用。

当然,不推荐使用同步调用。要使用异步调用,您有几个选项(查看官方文档):

  • Kotlin 协程(suspend关键字)
  • RxJava(将返回类型设置为Single, Maybe, Completable
  • 番石榴(将返回类型设置为ListenableFuture)。

此外,您可以使用 Threads/ThreadPools 将 DB 操作显式移动到后台线程,并自行管理异步工作(例如,使用回调)。

使用上述选项之一,您将在异步任务结束时收到通知(通知的方法取决于您选择的框架)。否则,您会进行同步调用并阻止 UI 线程。


推荐阅读