AsyncTask、AsyncTaskLoader 还是带有 ViewModel、LiveData 和 Room 的执行器?

AsyncTask, AsynTaskLoader or Executer with ViewModel, LiveData and Room?

首先,我不知道 Android 和 Java 中的所有内容,我正在努力,以防您发现我的问题缺乏知识。

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

出现并阅读 ViewModel and LiveData and Room and after reading this post 之后,尤其是在该部分 观察数据

In the Loader world, getting your data to your UI would involve a LoaderManager, calling initLoader() in the right place, and building a > ?LoaderCallbacks. The world is a bit more straightforward in the Architecture Components world. etc..

和下一节

加载所有东西第二段

For example, Room lets you have observarable queries — database queries that return LiveData so that database changes automatically propagate up through your ViewModel to your UI. Kind of like a CursorLoader without touching Cursors or Loaders.

以上所有意味着 ViewModelLiveData 以及 Room 可以在后台线程,我的意思是当我们使用 ViewModelLiveDataRoom 而不是 Loaders,我们不需要使用 AsyncTaskAsyncTaskLoader执行者

但在这些例子中:

android-room-with-a-view 可以用作模板,正如他们在 README.md、

中所说

MainActivity.java中他们写mWordViewModel.getAllWords().observe(this, .... ;,如果我们深入跟踪getAllWords(),我们发现该函数是查询select,但是当他们想在WordRepository.java插入数据时 或者 WordRoomDatabase.java 他们使用 AsyncTask,

我的意思是他们为什么使用 ViewModelLiveDataDao 查询 select,在 insert 的查询中,他们有 included AsyncTask ViewModelDao?, 因为正如上面所暗示的 ViewModelLiveData with Room 可以在后台线程?

中工作

我之前的问题针对这个例子 android-persistence 在 step3_solution,我的意思是 get 仅使用 ViewModel 数据,但要 insert DatabaseInitializer.javaAsyncTask 中的数据 是否包含?

此外,在 BasicSample 的示例中,当数据必须 插入时,Executer included

非常感谢

All of the above implies that ViewModel and LiveData with Room can work in the background thread, I mean when we use ViewModel and LiveData with Room instead of Loaders, we needn't have used AsyncTask or AsyncTaskLoader or 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

Loaders have been deprecated as of Android P (API 28). The recommended option for dealing with loading data while handling the Activity and Fragment lifecycles is to use a combination of ViewModels and LiveData. ViewModels survive configuration changes like Loaders but with less boilerplate. LiveData provides a lifecycle-aware way of loading data that you can reuse in multiple ViewModels. You can also combine LiveData using MediatorLiveData , and any observable queries, such as those from a Room database, can be used to observe changes to the data. ViewModels and LiveData are also available in situations where you do not have access to the LoaderManager, such as in a Service. Using the two in tandem provides an easy way to access the data your app needs without having to deal with the UI lifecycle. To learn more about LiveData see the LiveData guide and to learn more about ViewModels see the ViewModel guide.

In the MainActivity.java they write mWordViewModel.getAllWords().observe(this, .... ; and if we trace getAllWords() deeply we find that the function is query of select,

确实,getAllWords() 从 Room DAO 暴露为 LiveData<List<T>>,因此可以观察到,Room 内部将处理异步获取任务(在 ArchTaskExecutor.io() 上执行,这是two-threaded executor)。

@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 的查询正在跟踪底层数据库的失效,如果您执行的写入会更改此 table,则会为您重新查询结果集。这样,当您执行更改特定 table 中的元素的写入时,您不需要手动查询数据库。其实很方便。

插入只是插入。所以在那种情况下他们不会为你施展魔法。