android 架构组件中执行器的使用
Usage of executor in android architecture components
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());
}
});
}
}
以上代码是 "Guide to app architecture" 的一部分,来自 Android 文档,使用架构组件。在 refreshUser 方法中,如果缓存中不存在数据,他们会使用改造从网络中获取数据。
我的问题是:为什么他们为此使用执行器? Retrofit 本身已经能够 运行 异步网络请求。
请为我说明这个例子中执行器到底是什么以及它的需要。
开箱即用的房间不支持主线程上的数据库访问,因此执行程序在那里确保工作在单独的线程上完成。
通过使用执行器,他们还选择使用同步改造调用,这将阻塞正在执行的线程。
在您引用的代码中,执行器是 SingleThreadExecutor,这实际上创建了一个工作线程来执行其工作,在这种情况下,它将执行 Room DB 操作以及处理同步改造调用。
连同 newSingleThreadExecutor 的官方文档:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor()
What exactly is an Executor?
通常使用执行器而不是显式创建线程。例如,不是为一组任务中的每一个调用 new Thread(new RunnableTask()).start()
,您可以使用:
Executor executor = someExecutor(); // any class implementing `Executor` interface
executor.execute(new Runnable1());
executor.execute(new Runnable2());
Why do they use an executor for this? Retrofit itself is already
capable of running network request asynchronously.
他们用它从主线程切换到后台工作线程,执行数据库操作,因为默认情况下,Room架构组件不允许查询MainThread
.
Retrofit 能够执行异步网络请求,但他们在这里执行同步网络请求,之后他们只是使用 Room 组件对本地数据库执行插入操作。
有关Executor框架的更多信息,您可以按照以下指南进行操作:https://developer.android.com/reference/java/util/concurrent/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());
}
});
}
}
以上代码是 "Guide to app architecture" 的一部分,来自 Android 文档,使用架构组件。在 refreshUser 方法中,如果缓存中不存在数据,他们会使用改造从网络中获取数据。
我的问题是:为什么他们为此使用执行器? Retrofit 本身已经能够 运行 异步网络请求。
请为我说明这个例子中执行器到底是什么以及它的需要。
开箱即用的房间不支持主线程上的数据库访问,因此执行程序在那里确保工作在单独的线程上完成。
通过使用执行器,他们还选择使用同步改造调用,这将阻塞正在执行的线程。
在您引用的代码中,执行器是 SingleThreadExecutor,这实际上创建了一个工作线程来执行其工作,在这种情况下,它将执行 Room DB 操作以及处理同步改造调用。
连同 newSingleThreadExecutor 的官方文档: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor()
What exactly is an Executor?
通常使用执行器而不是显式创建线程。例如,不是为一组任务中的每一个调用 new Thread(new RunnableTask()).start()
,您可以使用:
Executor executor = someExecutor(); // any class implementing `Executor` interface
executor.execute(new Runnable1());
executor.execute(new Runnable2());
Why do they use an executor for this? Retrofit itself is already capable of running network request asynchronously.
他们用它从主线程切换到后台工作线程,执行数据库操作,因为默认情况下,Room架构组件不允许查询MainThread
.
Retrofit 能够执行异步网络请求,但他们在这里执行同步网络请求,之后他们只是使用 Room 组件对本地数据库执行插入操作。
有关Executor框架的更多信息,您可以按照以下指南进行操作:https://developer.android.com/reference/java/util/concurrent/Executor