AsyncTask,AsynTaskLoader或具有ViewModel,LiveData和Room的执行器?

时间:2019-03-12 05:23:57

标签: java android android-room android-livedata android-viewmodel

首先,我不了解Android和Java的所有知识,以防万一您对我的问题不了解。

当我读到Loaders的好处时,我读到了加载程序在单独的线程上运行,以防止UI无响应。

出现并阅读ViewModelLiveData房间之后,并阅读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的示例中,当必须插入数据时,包含执行者吗?

非常感谢您

2 个答案:

答案 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的查询正在跟踪基础数据库的无效性,如果您执行了更改此表的写入操作,则将为您重新查询结果集。这样,当您执行更改特定表中元素的写入操作时,无需手动查询数据库。实际上,这非常方便。

插入只是插入。因此,在这种情况下,他们不会为您做魔术。