Android架构组件networking线程

我目前正在查看以下指南: https : //developer.android.com/topic/libraries/architecture/guide.html

networkBoundResource类:

// ResultType: Type for the Resource data // RequestType: Type for the API response public abstract class NetworkBoundResource<ResultType, RequestType> { // Called to save the result of the API response into the database @WorkerThread protected abstract void saveCallResult(@NonNull RequestType item); // Called with the data in the database to decide whether it should be // fetched from the network. @MainThread protected abstract boolean shouldFetch(@Nullable ResultType data); // Called to get the cached data from the database @NonNull @MainThread protected abstract LiveData<ResultType> loadFromDb(); // Called to create the API call. @NonNull @MainThread protected abstract LiveData<ApiResponse<RequestType>> createCall(); // Called when the fetch fails. The child class may want to reset components // like rate limiter. @MainThread protected void onFetchFailed() { } // returns a LiveData that represents the resource public final LiveData<Resource<ResultType>> getAsLiveData() { return result; } } 

我在这里对使用线程有点困惑。
为什么@MainThread适用于networkIO?
此外,为了保存到数据库,应用@WorkerThread,而@MainThread检索结果。

NetworkIO和本地数据库交互默认使用工作线程是不好的做法吗?

我也看看下面的演示(GithubBrowserSample): https : //github.com/googlesamples/android-architecture-components
这使我从一个线程的angular度困惑。
演示程序使用executors框架,并为networkIO定义了一个包含3个线程的固定池,但在演示中,只有一个工作任务被定义为一个调用,即FetchNextSearchPageTask 。 所有其他networking请求似乎在主线程上执行。

有人可以澄清理由吗?

Solutions Collecting From Web of "Android架构组件networking线程"

看来你有一些误解。

一般来说,从Main(UI)线程调用networking是不可能的,但是除非你有大量的数据,否则可以在主线程中从DB获取数据。 这就是Google的例子。

1。

演示程序使用executors框架,并为networkIO定义了一个包含3个线程的固定池,但在演示中,只有一个工作任务被定义为一个调用,即FetchNextSearchPageTask。

首先,从Java 8开始,您可以使用lambda语法创build一些接口(所谓的“function接口”)的简单实现。 这是在NetworkBoundResource中发生的事情:

  appExecutors.diskIO().execute(() -> { saveCallResult(processResponse(response)); appExecutors.mainThread().execute(() -> // we specially request a new live data, // otherwise we will get immediately last cached value, // which may not be updated with latest results received from network. result.addSource(loadFromDb(), newData -> result.setValue(Resource.success(newData))) ); }); 

第一个任务( processResponsesaveCallResult )在diskIO Executor程序提供的线程上进行调度,然后从该线程将剩下的工作安排回主线程。

2。

为什么@MainThread适用于networkIO?

所有其他networking请求似乎在主线程上执行。

事实并非如此。 只有结果包装,即在主线程上创buildLiveData<ApiResponse<RequestType>> 。 networking请求在另一个线程上完成。 这是不容易看到的,因为Retrofit库被用来完成所有与networking有关的繁重工作,并很好地隐藏了这种实现细节。 不过,如果您查看将Retrofit封装到LiveData ,则可以看到使用了LiveData ,这实际上是一个asynchronous调用(由Retrofit内部调度)。

其实,如果不是“分页”function,这个例子根本就不需要networkIO Executor 。 “分页”是一个复杂的function,因此它使用显式的FetchNextSearchPageTask来实现,这是一个我认为Google例子做得不是很好的地方: FetchNextSearchPageTask不会重复使用来自RepoRepository请求parsing逻辑(即processResponse ),而是假设这是微不足道的(现在是这样,但谁知道未来…)。 此外,还没有将合并作业安排到diskIO Executor ,这也与响应处理的其余部分不一致。