【发布时间】:2019-05-11 08:09:55
【问题描述】:
我在guide from code labs 之后创建了一个房间数据库,它利用存储库来:
存储库管理查询线程并允许您使用多个后端。在最常见的示例中,存储库实现了决定是从网络获取数据还是使用缓存在本地数据库中的结果的逻辑。
我按照指南进行操作,现在可以创建实体并检索数据。我什至更进一步,在指南范围之外创建了另一个完整的实体。
但是我找不到很多使用这种 MVVM(?) 风格的资源,所以我很难真正理解存储库。现在我想更新一个字段。只有一个,好像我能够管理其余的应该是相似的。
我想更新一个名为 dartshit 的字段,我为此创建了 dao 方法:
@Query("UPDATE AtcUserStats SET dartsHit = :amount WHERE userName = :userName") void UpdateHitAmount(int amount, String userName);
我有一个存储库,我假设它用于所有实体:
public class UsersRepository {
private UsersDao mUsersDao;
private AtcDao mAtcDao;
private LiveData<List<Users>> mAllUsers;
private LiveData<List<AtcUserStats>> mAllAtc;
private AtcUserStats mAtcUser;
UsersRepository(Application application) {
AppDatabase db = AppDatabase.getDatabase(application);
mUsersDao = db.usersDao();
mAtcDao = db.atcDao();
mAllUsers = mUsersDao.fetchAllUsers();
mAllAtc = mAtcDao.getAllAtcStats();
}
LiveData<List<Users>> getAllUsers() {
return mAllUsers;
}
LiveData<List<AtcUserStats>> getAllAtcStats() {
return mAllAtc;
}
LiveData<AtcUserStats> getAtcUser(String username) {
return mAtcDao.findByName(username);
}
public void insert (Users user) {
new insertAsyncTask(mUsersDao).execute(user);
}
public void insertAtc (AtcUserStats atc) {
new insertAsyncAtcTask(mAtcDao).execute(atc);
}
private static class insertAsyncTask extends AsyncTask<Users, Void, Void> {
private UsersDao mAsyncTaskDao;
insertAsyncTask(UsersDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Users... params) {
mAsyncTaskDao.insertNewUser(params[0]);
return null;
}
}
private static class insertAsyncAtcTask extends AsyncTask<AtcUserStats, Void, Void> {
private AtcDao mAsyncTaskDao;
insertAsyncAtcTask(AtcDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final AtcUserStats... params) {
mAsyncTaskDao.insertNewAtcUser(params[0]);
return null;
}
}
}
我的问题是如何为我尝试在此存储库中运行的更新查询创建 AsyncTask?
这是我迄今为止通过广泛复制插入存储库方法所得到的:
private class updateHitAsyncTask {
private AtcDao mAsyncTaskDao;
public updateHitAsyncTask(AtcDao mAtcDao) {
mAsyncTaskDao = mAtcDao;
}
protected Void doInBackground(int amount, String name) {
mAsyncTaskDao.UpdateHitAmount(amount, name);
return null;
}
}
不正确的是我收到 llegalStateException: Cannot access database on the main thread 因为它可能会长时间锁定 UI。 错误。但我认为这个 AsyncTask 应该会处理这个问题?
这是我的视图模型中的更新方法,它报告了 0 个错误:
void updateHitAmount (int amount, String name) {
mRepository.updateAtcHits(amount, name);
}
这是我实际上试图将所有这些联系在一起的 UI 代码,我怀疑必须有更好的方法使用 onChanged 来简单地更新一个字段,但我再次努力在存储库中找到关于谷歌的任何建议方法:
private void callOnChanged() {
mAtcViewModel = ViewModelProviders.of(this).get(AtcViewModel.class);
mAtcViewModel.getAllUsers().observe(this, new Observer<List<AtcUserStats>>() {
@Override
public void onChanged(@Nullable final List<AtcUserStats> atc) {
// Update the cached copy of the users in the adapter.
for (int i = 0; i < atc.size(); i++) {
if (atc.get(i).getUserName().equals(mUser)) {
mAtcViewModel.updateHitAmount(55, mUser);
//atc.get(i).setDartsHit(55);
Log.d("id", String.valueOf(userSelected.getId()));
}
}
}
});
如何在后台线程上使用这种方法更新字段?
【问题讨论】:
标签: java android sqlite android-room