首页 > 解决方案 > android架构组件中executor的使用

问题描述

public class UserRepository {
private final Webservice webservice;
private final UserDao userDao;
private final Executor executor;

@Inject
public UserRepository(Webservice webservice, UserDao userDao, Executor executor) {
    this.webservice = webservice;
    this.userDao = userDao;
    this.executor = executor;
}

public LiveData<User> getUser(String userId) {
    refreshUser(userId);
    // Returns a LiveData object directly from the database.
    return userDao.load(userId);
}

private void refreshUser(final String userId) {
    // Runs in a background thread.
    executor.execute(() -> {
        // Check if user data was fetched recently.
        boolean userExists = userDao.hasUser(FRESH_TIMEOUT);
        if (!userExists) {
            // Refreshes the data.
            Response<User> response = webservice.getUser(userId).execute();

            // Check for errors here.

            // Updates the database. The LiveData object automatically
            // refreshes, so we don't need to do anything else here.
            userDao.save(response.body());
        }
    });
}
}

上面的代码是“应用架构指南”的一部分,来自 Android 文档,使用架构组件。在refreshUser方法中,如果缓存中不存在数据,他们会使用改造从网络中获取数据。

我的问题是:他们为什么要为此使用执行者?Retrofit 本身已经能够异步运行网络请求。

请在此示例中说明什么是 Executor 及其对我的需求。

标签: androidmultithreadingandroid-roomandroid-architecture-components

解决方案


开箱即用的房间不支持主线程上的数据库访问,因此执行器在那里确保工作在单独的线程上完成。

通过使用执行器,他们还选择使用同步改造调用,这将阻塞执行线程。

在您引用的代码中,执行器是一个 SingleThreadExecutor,这实际上创建了一个工作线程来执行其工作,在这种情况下,它将执行 Room DB 操作以及处理同步改造调用。

这是上面示例中执行程序的链接。 https://github.com/PhilippeBoisney/GithubArchitectureComponents/blob/98e0a048791f18646c730323c242c670c3eaf453/app/src/main/java/com/boisneyphilippe/githubarchitecturecomponents/di/module/AppModule.java#L48

连同 newSingleThreadExecutor 的官方文档: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor()


推荐阅读