首先,我不了解Android和Java的所有知识,以防万一您对我的问题不了解。
当我读到Loaders的好处时,我读到了加载程序在单独的线程上运行,以防止UI无响应。
出现并阅读ViewModel和LiveData和房间之后,并阅读this post之后,尤其是在本节中 观察数据,其中显示
在
Loader
的世界中,将数据获取到用户界面将涉及LoaderManager
,在正确的位置调用initLoader()
,并构建一个>?LoaderCallbacks
。在这个世界上,世界变得更加简单了 建筑构件世界。等。
和下一节
加载第二段中所述的所有内容
例如,Room允许您进行可观察的查询-数据库查询 返回
LiveData
,以便数据库更改自动向上传播 通过ViewModel
到用户界面。有点像CursorLoader
而没有 触摸游标或加载程序。
以上所有内容都意味着具有 Room 的 ViewModel 和 LiveData 可以在后台线程中工作,意味着当我们在 Room 中使用 ViewModel 和 LiveData 而不是 Loaders 时,我们不需要使用 AsyncTask 或 AsyncTaskLoader 或 Executer
但是在这些示例中:
android-room-with-a-view可以用作模板,正如他们在README.md中所说的
在 MainActivity.java 中,他们写了mWordViewModel.getAllWords().observe(this, .... ;
,如果我们深入跟踪getAllWords()
,我们会发现该函数是 select 的查询,但是当他们想在 WordRepository.java 中插入数据时
或 WordRoomDatabase.java ,它们使用 AsyncTask ,
我的意思是为什么他们在查询 select 时使用 ViewModel 和 LiveData 和 Dao 对插入的查询中,它们已包含 AsyncTask 和 ViewModel 和 Dao ?,因为 ViewModel 和 LiveData 与 Room 上方的含义意味着可以在后台线程中工作?
我的上一个问题针对此示例android-persistence at step3_solution,我的意思是仅使用 ViewModel 来获取数据,而插入 包含了{strong> AsyncTask 这样的数据吗?
在DatabaseInitializer.java的示例中,当必须插入数据时,包含了执行者吗?
非常感谢您
答案 0 :(得分:0)
以上所有内容都意味着带有Room的ViewModel和LiveData可以在后台线程中工作,这意味着当我们使用带有Room的ViewModel和LiveData而不是Loaders时,我们不必使用AsyncTask或AsyncTaskLoader或Executer
他们没有。它们在执行的当前线程上运行。这就是为什么在您引用的示例中,他们仍然使用AsyncTask将工作移至后台线程。
还请注意MutableLiveData有两种方法来设置其值。
public void postValue(T value) {
super.postValue(value);
}
public void setValue(T value) {
super.setValue(value);
}
postValue(value)
用于在后台线程中设置MutableLiveData
的值。如果我没记错的话,在后台调用setValue(value)
会抛出异常。
此外,从API 28开始不推荐使用加载程序。您可以阅读here。
从Android P(API 28)开始不推荐使用加载程序。建议在处理活动和片段生命周期时处理加载数据的选项是结合使用ViewModels和LiveData。 ViewModels能够像Loader这样的配置更改得以保留,但样板更少。 LiveData提供了一种生命周期感知的方式加载数据,您可以在多个ViewModel中重用。您还可以使用MediatorLiveData组合LiveData,并且可以使用任何可观察到的查询(例如来自Room数据库的查询)来观察数据的变化。在无法访问LoaderManager的情况下(例如在Service中),ViewModels和LiveData也可用。串联使用两者提供了一种简单的方法,无需处理UI生命周期即可访问应用程序所需的数据。要了解有关LiveData的更多信息,请参见LiveData指南;要了解有关ViewModel的更多信息,请参见ViewModel指南。
答案 1 :(得分:0)
在MainActivity.java中,他们编写了mWordViewModel.getAllWords()。observe(this,....;如果深入跟踪getAllWords(),我们会发现该函数是对select的查询,
实际上,getAllWords()
从Room DAO暴露为LiveData<List<T>>
,因此可以观察到,并且Room在内部将处理异步提取任务(在ArchTaskExecutor.io()
上执行,这是一个{ {3}})。
@Query("SELECT * from word_table ORDER BY word ASC") LiveData<List<Word>> getAlphabetizedWords();
但是,如果您有insert
,则在Room DAO上是同步方法,因此它们不会为您处理线程。
AsyncTask是一种在后台执行默认任务的Android默认执行器上读取代码的特殊方法:
public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
依次执行每个任务。
所以您的问题的答案是因为查询和插入的工作方式不同。
公开为LiveData的查询正在跟踪基础数据库的无效性,如果您执行了更改此表的写入操作,则将为您重新查询结果集。这样,当您执行更改特定表中元素的写入操作时,无需手动查询数据库。实际上,这非常方便。
插入只是插入。因此,在这种情况下,他们不会为您做魔术。