【问题标题】:How do I update a field in a room database using a repository & viewmodel如何使用存储库和视图模型更新房间数据库中的字段
【发布时间】: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


    【解决方案1】:

    由于这个答案here 而想通了。这主要是因为我对 AsyncTask 缺乏了解。本质上,我需要创建一个对象并以这种方式传递数据,然后在后台执行:

     private static class MyTaskParams {
        int amount;
        String name;
    
        MyTaskParams(int amount, String name) {
            this.amount = amount;
            this.name = name;
        }
    }
    
    public void updateAtcHits (int amount, String name) {
    
        MyTaskParams params = new MyTaskParams(amount,name);
        new updateHitAsyncTask(mAtcDao).execute(params);
    }
    
    private class updateHitAsyncTask extends AsyncTask<MyTaskParams,Void,Void>{
    
        private AtcDao mAsyncTaskDao;
    
        public updateHitAsyncTask(AtcDao mAtcDao) {
    
            mAsyncTaskDao = mAtcDao;
        }
    
        @Override
        protected Void doInBackground(MyTaskParams... myTaskParams) {
            int amount =myTaskParams[0].amount;
            String name = myTaskParams[0].name;
            mAsyncTaskDao.UpdateHitAmount(amount, name);
            return null;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-09
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      相关资源
      最近更新 更多