web-dev-qa-db-ja.com

新しいスレッドとデータバインディングの問題があるルーム永続ライブラリ

Android Room Persistentライブラリに取り組んでいます。プロジェクトに双方向データバインディングも実装しています。プロジェクトでは、フォームに入力してすべてのユーザーを行に表示することでユーザーを挿入しています特定のユーザー行をクリックして更新します。以下は私のUserDaoクラスです。

_@Dao
public interface UserDao {

  @Query("SELECT * FROM user")
  List<User> getAllUsers();

  @Insert
  void insertAll(User... users);

  @Update
  void updateUser(User... users);

  @Query("SELECT * FROM user WHERE user_id IN (:userId)")
  User getSpecifiedUser(int...userId);
 }
_

データバインディングの場合、UserFormActivityでユーザーモデルをバインディングしています

binding.setUserModel(userModel);

現在、Room永続ライブラリではメインスレッドでデータベース操作を実行できないため、ユーザーを更新するために、次のように新しいスレッドの行をクリックして、ユーザーフォームで特定のユーザーのデータを取得しています。

_ private void getUserFormData(final int userId) {
    try {
        Thread t = new Thread(new Runnable() {
            public void run() {
                userModel = db.userDao().getSpecifiedUser(userId);
            }
        }, "Thread A");
        t.start();
    } catch (NumberFormatException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
_

更新のためにuserModelでユーザーのデータを取得した後、データバインディングが実行されるユーザーフォームにユーザーデータを反映させたいのですが、反映されていません。私はこの問題で立ち往生しています。

9

プロジェクトにLiveDataとViewModelを実装し、UserListActivityでLifecycleActivityを拡張しました。これが私のAddUserViewModelクラスです:

_public class AddUserViewModel extends AndroidViewModel {
     private UserDatabase userDatabase;

     public AddUserViewModel(Application application) {
      super(application);

     userDatabase = UserDatabase.getDatabase(this.getApplication());
     }

     public void addUser(User user) {
     new AddUserAsyncTask(userDatabase).execute(user);
     }

     private static class AddUserAsyncTask extends AsyncTask<User, Void, 
        Void> {

        private UserDatabase db;

        public AddUserAsyncTask(UserDatabase userDatabase) {
             db = userDatabase;
        }

     @Override
     protected Void doInBackground(User... params) {
         db.userDao().insertUser(params);
         return null;
         }
     }

    public User getSpecificUserData(int userId) {
        User user = null;
        try {
             user = new 
             getUserDataAsyncTask(userDatabase).execute(userId).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
           }
        return user;
    }

    private static class getUserDataAsyncTask extends AsyncTask<Integer, 
        Void, User> {

        private UserDatabase db;

        public getUserDataAsyncTask(UserDatabase userDatabase) {
            db = userDatabase;
        }

        @Override
        protected User doInBackground(Integer... userId) {
            User user = db.userDao().getSpecifiedUser(userId);
            return user;
        }

        @Override
        protected void onPostExecute(User user) {
            super.onPostExecute(user);
        }
      }
  }
_

AddUserActivityで、データベースメソッドから特定のユーザーデータを取得しています。

userModel = addUserViewModel.getSpecificUserData(userId);

送信ボタンをクリックするとデータが更新されます。 My UserListActivityは、ユーザーリストが監視されるLifecycleActivityを拡張し、変更があると、次のようにUseリストを更新します。

_ userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);

    userViewModel.getUserList().observe(UserListActivity.this, new 
    Observer<List<User>>() {
        @Override
        public void onChanged(@Nullable List<User> user) {
            adapter.addItems(user);
        }
    });
_

これは私にとってはうまくいきました、そして私は私の解決策を得ました!

10