Android 具有 return 值(long 或 int)的 Room DAO @Insert 如何工作?

How does Android Room DAO @Insert with return value(long or int) work?

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

@Insert
long insertTransaction(Transaction transaction);

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

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

<!-- 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)

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

From what I understand, all the @Insert, @Update, or @Query are executed asynchronously.

默认情况下,所有@Insert、@Update 或@Query 都是同步执行的。 Room 会警告您,如果不在 RoomDatabase.Builder.

中显式使用方法 allowMainThreadQueries,您将无法进行同步调用

当然不推荐使用同步调用。要使用异步调用,您有多种选择(查看 official documentation):

  • Kotlin 协程(suspend 关键字)
  • RxJava(设置return类型为SingleMaybeCompletable
  • Guava(将 return 类型设置为 ListenableFuture)。

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

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