android - 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 及其对我的需求。
解决方案
开箱即用的房间不支持主线程上的数据库访问,因此执行器在那里确保工作在单独的线程上完成。
通过使用执行器,他们还选择使用同步改造调用,这将阻塞执行线程。
在您引用的代码中,执行器是一个 SingleThreadExecutor,这实际上创建了一个工作线程来执行其工作,在这种情况下,它将执行 Room DB 操作以及处理同步改造调用。
连同 newSingleThreadExecutor 的官方文档: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor()
推荐阅读
- java - Drools 将一个对象的列表转换为 Drools 中的另一个对象的列表
- api - Hashicorp Vault 在尝试删除不存在的密钥时返回 400 而不是 404
- docker - Nexus Docker 注册表:blob 未知:blob 对注册表未知
- laravel - Laravel 8 通过三个链接模型进行计数
- apache-spark - 使用 Pyspark 将纪元秒转换为时间戳
- python - Python - 比较 2 个 csv 文件并删除行
- javascript - 试图在 js 中添加两个整数,但不知何故如果 Integer 很大,而不使用任何内置库来处理大整数
- c# - FirebaseAuth.DefaultInstance 与另一个实例竞争 -> 只有一个有效
- kivy - kivy recycleview gridlayout如何显示单行
- pycharm - 我安装了pycharm,它甚至无法启动并显示启动错误我尝试重新安装它但没有任何效果