会议室数据库将返回1个额外的对象

时间:2019-10-12 15:52:29

标签: android android-room android-livedata

我有一个Room DB类,它创建3个用户对象-

@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class UserDatabase extends RoomDatabase {

  private static UserDatabase instance;

  public abstract UserDao userDao();

  public static synchronized UserDatabase getInstance(Context context) {

    Log.d("inside observe - ", "inside database");

    if (instance == null) {
      instance = Room.databaseBuilder(context.getApplicationContext(), UserDatabase.class, "user_database").fallbackToDestructiveMigration().addCallback(roomUserCallback).build();
    }
    return instance;
  }

  private static RoomDatabase.Callback roomUserCallback = new RoomDatabase.Callback() {

    @Override
    public void onCreate(@NonNull SupportSQLiteDatabase db) {
      super.onCreate(db);
      new PopulateDbAsyncTask(instance).execute();
    }
  };

  //TODO - delete this in the future. This is just for populating.
  private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {

    static final String URL = "https://www.shortlist.com/media/images/2019/05/40-favourite-songs-of-famous-people-28-1556672663-9rFo-column-width-inline.jpg";
    static final String URL2 = "https://img-s-msn-com.akamaized.net/tenant/amp/entityid/BBR9VUw.img?h=416&amp;w=624&amp;m=6&amp;q=60&amp;u=t&amp;o=f&amp;l=f&amp;x=2232&amp;y=979";
    static final String URL3 = "https://dz9yg0snnohlc.cloudfront.net/new-what-famous-people-with-depression-have-said-about-the-condition-1.jpg";
    private UserDao userDao;

    private PopulateDbAsyncTask(UserDatabase db) {
      userDao = db.userDao();
    }

    @Override
    protected Void doInBackground(Void... voids) {
      userDao.insert(new User(URL, "Barak Obama1", "/@BarakObama1"));
      userDao.insert(new User(URL2, "Barak Obama2", "/@BarakObama2"));
      userDao.insert(new User(URL3, "Barak Obama3", "/@BarakObama3"));
      return null;
    }
  }
}

我正在使用viewmodel以便将用户作为LiveData来获取。 由于某种原因,在我第一次安装我的应用程序时,我创建了一个额外的“ barak obama1”用户,并且紧随其后,依次订购了所有3个“普通”用户-barak obama3、2和1。 这是我的MainActivity-

private ArrayList<User> usersList;
@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    fetchUserList();
  }

  private void fetchUserList() {
    userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
    final Observer<List<User>> userObserver = users -> {
      Log.d("inside observe - ", "inside main activity, list size - " + users.size());
      usersList = (ArrayList) users;
      initViewsAndListeners();
      addCards();
    };
    userViewModel.getAllUsers().observe(this, userObserver);
  }

  private void addCards(){
    TinderCardView tinderCardView;
    for (int i = 0; i < usersList.size(); i++) {
      tinderCardView = new TinderCardView(this);
      tinderCardView.bind(usersList.get(i));
      Log.d("inside observe - ", "inside main activity, user value - " + usersList.get(i).getUsername());
      tinderStackLayout.addCard(tinderCardView);
      Log.d("addCardCalled - ", "\nindex value - " + i + "\n" +
          "userlist size - " + usersList.size());
    }
  }

  @Override
  public void onClick(View view) {
    int buttonTag = Integer.valueOf(String.valueOf(view.getTag()));
    TinderCardView topCardOnStack = tinderStackLayout.getTopCardOnStack();
    topCardOnStack.handleButtonPressed(buttonTag);
//    if (buttonTag == 1) { // TODO - move logic to card class
//       userViewModel.delete(usersList.get(0));
//       //fetchUserList();
//    }
  }

  private void initViewsAndListeners() {
    tinderStackLayout = findViewById(R.id.activity_main_tinder_stack_layout);
    mDeleteButton = findViewById(R.id.activity_main_delete_button);
    mPassButton = findViewById(R.id.activity_main_pass_button);
    mApproveButton = findViewById(R.id.activity_main_approve_button);
    mDeleteButton.setOnClickListener(this);
    mApproveButton.setOnClickListener(this);
    mPassButton.setOnClickListener(this);
  }

您可以看到我到处都有日志消息,因此您可以了解我现在要向您显示的内容。我首先获得一个额外的用户,即“ barak obama1”用户,然后再获得所有其他3个用户-

enter image description here

livedata指出列表中有1个用户,将其添加为卡,然后DB创建新对象,livedata调用该方法,又增加了3个用户。

为什么会这样?如果他解决了这个问题,我很乐意亲吻某人的腿,不要开玩笑。

编辑-

这是我的ViewModel-

public class UserViewModel extends AndroidViewModel {

  private UserRepository repository;
  private LiveData<List<User>> allUsers;

  public UserViewModel(@NonNull Application application) {
    super(application);
    repository = new UserRepository(application);
    allUsers = repository.getAllUsers();

  }

  public void insert(User user) {
    repository.insert(user);
  }

  public void update(User user) {
    repository.update(user);
  }

  public void delete(User user) {
    repository.delete(user);
  }

  public void deleteAllUsers(){
    repository.deleteAllUsers();
  }

  public LiveData<List<User>> getAllUsers() {
    Log.d("inside observe - ", "inside viewmodel");
    return allUsers;
  }
}

和我的存储库-

public class UserRepository {

  private UserDao userDao;
  private LiveData<List<User>> allUsers;

  public UserRepository(Application application) {
    UserDatabase database = UserDatabase.getInstance(application);
    userDao = database.userDao();
    allUsers = userDao.getAllUsers();
  }

  public void insert(User user) {
    new InsertUserAsyncTask(userDao).execute(user);
  }

  public void update(User user) {
    new UpdateUserAsyncTask(userDao).execute(user);
  }

  public void delete(User user) {
    new DeleteUserAsyncTask(userDao).execute(user);
  }

  public void deleteAllUsers() {
    new DeleteAllUsersAsyncTask();
  }

  public LiveData<List<User>> getAllUsers() {
    Log.d("inside observe - ", "inside repository");
    return allUsers;
  }

  //TODO - migrate all 4 async tasks into one.
  private static class InsertUserAsyncTask extends AsyncTask<User, Void, Void> {

    private UserDao userDao;

    private InsertUserAsyncTask(UserDao userDao) {
      this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(User... users) {
      userDao.insert(users[0]);
      return null;
    }
  }

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

    private UserDao userDao;

    private UpdateUserAsyncTask(UserDao userDao) {
      this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(User... users) {
      userDao.update(users[0]);
      return null;
    }
  }

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

    private UserDao userDao;

    private DeleteUserAsyncTask(UserDao userDao) {
      this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(User... users) {
      userDao.delete(users[0]);
      return null;
    }
  }

  private static class DeleteAllUsersAsyncTask extends AsyncTask<Void, Void, Void> {

    private UserDao userDao;

    private DeleteAllUsersAsyncTask() {
      this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(Void... voids) {
      userDao.deleteAllUsers();
      return null;
    }
  }


}

编辑-

这是我的岛-

@Dao
public interface UserDao {

  @Insert
  void insert(User user);

  @Update
  void update(User user);

  @Delete
  void delete(User user);

  @Query("DELETE FROM user_table")
  void deleteAllUsers();

  @Query("SELECT * FROM user_table ORDER BY id DESC")
  LiveData<List<User>> getAllUsers();




}

2 个答案:

答案 0 :(得分:1)

尝试了解 我发表了评论

这是原始代码,只是为了给您提供想法

private ArrayList<User> usersList;

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    this.usersList = new ArrayList(); // initalise the array list here
    fetchUserList();
  }

  private void fetchUserList() {
    userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
    final Observer<List<User>> userObserver = users -> {
      Log.d("inside observe - ", "inside main activity, list size - " + users.size());
      usersList = (ArrayList) users; //dont do this ! instead follow the below instructions
      // to do
      for(User user : users){
        if(!usersList.contains(user)){
            usersList.add(user);
        }
      }
      // to do ends here
      initViewsAndListeners();
      addCards();
    };
    userViewModel.getAllUsers().observe(this, userObserver);
  }

}

看看我做了什么:

  • 启动用户列表
  • 当观察用户实时数据时,我使用循环,在该循环中 检查是否已添加此用户

你懂吗?

答案 1 :(得分:1)

在1个事务中插入所有用户。 2种方法: 1.在dao中创建一个接收用户列表的函数。 2.在roomDB中创建交易(谷歌如何。非常简单)

我喜欢第一个