Как мне обновить поле в базе данных комнаты, используя репозиторий и модель представления - PullRequest
0 голосов
/ 11 мая 2019

Я создал базу данных помещений, следуя этому руководству из лаборатории кодов . Он использует репозиторий для:

Репозиторий управляет потоками запросов и позволяет использовать несколько бэкэндов.В наиболее распространенном примере репозиторий реализует логику для принятия решения, извлекать ли данные из сети или использовать результаты, кэшированные в локальной базе данных.

Я следовал этому руководству и теперь могу создаватьсущность и получить данные.Я даже пошел дальше и создал еще одно целое, выходящее за рамки руководства.

Однако я не могу найти много ресурсов, которые используют этот стиль MVVM (?), Поэтому изо всех сил пытаюсь понять хранилище.А пока я хочу обновить поле.Только один, как будто я могу управлять тем, что остальные должны быть похожи.

Я хочу обновить поле с именем dartshit, и для этого создан метод dao:

@ Query ("UPDATE AtcUserStats SET dartsHit =: сумма 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 для запроса на обновление Iпытаюсь запустить в этом хранилище?

Вот то, что у меня есть, широко скопировав методы репозитория вставки:

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: Невозможно получить доступ к базе данных наосновной поток, поскольку он может потенциально заблокировать пользовательский интерфейс на длительный период времени. ошибка.Но я думал, что AsyncTask должен позаботиться об этом?

Вот мой метод обновления в моей модели представления, который сообщает 0 ошибок:

  void updateHitAmount (int amount, String name) {
    mRepository.updateAtcHits(amount, name);
}

и вот код пользовательского интерфейсагде я на самом деле пытаюсь связать все это вместе, я подозреваю, что должен быть лучший способ, с помощью onChanged для простого обновления поля, но опять же я изо всех сил пытаюсь найти любой совет по Google с подходом хранилища:

   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()));
                }
            }
        }
    });

Как я могу обновить поля, используя этот подход в фоновом потоке?

1 Ответ

0 голосов
/ 11 мая 2019

Понял это благодаря этому ответу здесь . Это было в основном из-за моего непонимания 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...