将当前值与架构组件中的最新值进行比较
Comparing current values with last values in architecture component
我从 api
得到一个复杂的 json
,我用 Architect component(Room)
.
保存值
问题:
- 我可以将当前值与我在
SQlite
中保存的上一个值进行比较吗?如果在比较中我发现不同,请更新 RecyclerView
?
- 这个方法合乎逻辑吗?
- 你有更好的方式提供吗?
- 如果你有更好的方式提供给我一个样品(url样品)
是的,你可以这样做,这实际上是推荐的方式。为此,我认为您应该利用 Android Jetpack 引入的另外两个架构组件,不仅是 Room
数据库:ViewModel and LiveData,但这不是强制性的。
重要的是为您的应用程序添加一个额外的层,名为 Repository
:
Repository modules handle data operations. They provide a clean API so
that the rest of the app can retrieve this data easily. They know
where to get the data from and what API calls to make when data is
updated. You can consider repositories to be mediators between
different data sources, such as persistent models, web services, and
caches.
所以基本上,处理此问题的建议架构如下所示:
考虑到这一点,从网络服务检索用户数据并将其保存到本地房间数据库的存储库示例如下所示:
public class UserRepository {
private final Webservice webservice;
private final UserDao userDao;
private final Executor executor;
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());
}
});
}
}
然后,您的 ViewModel 将获取用户实时数据,执行如下操作:
...
user = userRepo.getUser(userId);
...
并且它将使用 public 方法将该 LiveData 提供给 UI 层:
...
public LiveData<User> getUser() {
return this.user;
}
...
最后,从您的 UI 图层(Activity 或片段)您可以 观察 ViewModel 中的 LiveData 并调整 UI相应地。
viewModel.getUser().observe(this, user -> {
// Update UI.
});
要获得更完整的解释,建议您查看:
您可以将来自服务器和 sqlite 的多个实时数据源与 LiveData 的子类 MediatorLiveData 合并。
例如,如果您的 UI 中有一个可以从本地数据库或网络更新的 LiveData 对象,那么您可以将以下源添加到 MediatorLiveData 对象:
A LiveData object associated with the data stored in the database.
A LiveData object associated with the data accessed from the network.
我从 api
得到一个复杂的 json
,我用 Architect component(Room)
.
问题:
- 我可以将当前值与我在
SQlite
中保存的上一个值进行比较吗?如果在比较中我发现不同,请更新RecyclerView
? - 这个方法合乎逻辑吗?
- 你有更好的方式提供吗?
- 如果你有更好的方式提供给我一个样品(url样品)
是的,你可以这样做,这实际上是推荐的方式。为此,我认为您应该利用 Android Jetpack 引入的另外两个架构组件,不仅是 Room
数据库:ViewModel and LiveData,但这不是强制性的。
重要的是为您的应用程序添加一个额外的层,名为 Repository
:
Repository modules handle data operations. They provide a clean API so that the rest of the app can retrieve this data easily. They know where to get the data from and what API calls to make when data is updated. You can consider repositories to be mediators between different data sources, such as persistent models, web services, and caches.
所以基本上,处理此问题的建议架构如下所示:
考虑到这一点,从网络服务检索用户数据并将其保存到本地房间数据库的存储库示例如下所示:
public class UserRepository {
private final Webservice webservice;
private final UserDao userDao;
private final Executor executor;
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());
}
});
}
}
然后,您的 ViewModel 将获取用户实时数据,执行如下操作:
...
user = userRepo.getUser(userId);
...
并且它将使用 public 方法将该 LiveData 提供给 UI 层:
...
public LiveData<User> getUser() {
return this.user;
}
...
最后,从您的 UI 图层(Activity 或片段)您可以 观察 ViewModel 中的 LiveData 并调整 UI相应地。
viewModel.getUser().observe(this, user -> {
// Update UI.
});
要获得更完整的解释,建议您查看:
您可以将来自服务器和 sqlite 的多个实时数据源与 LiveData 的子类 MediatorLiveData 合并。
例如,如果您的 UI 中有一个可以从本地数据库或网络更新的 LiveData 对象,那么您可以将以下源添加到 MediatorLiveData 对象:
A LiveData object associated with the data stored in the database.
A LiveData object associated with the data accessed from the network.