【发布时间】:2019-10-12 15:52:29
【问题描述】:
我有一个创建 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&w=624&m=6&q=60&u=t&o=f&l=f&x=2232&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 -
livedata 发现列表中有 1 个用户,作为卡片添加,然后数据库创建新对象,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();
}
【问题讨论】:
-
实时数据就是这样工作的。它没有返回任何额外的东西。它正在返回您要求它返回的内容。因此,当您渲染数据时,请检查您是否已经渲染了数据,如果没有则渲染它。简单!!!
-
你的意思是,在数据库类中我应该检查我是否已经上传了数据?如果是的话 - 你能告诉我根据我提供的数据库类正确的方法是什么吗?
-
你的
ViewModel是什么样的? -
@Md.Asaduzzaman 编辑并添加了视图模型和存储库
-
尝试在
addCards()的第一行添加tinderStackLayout.removeAllViews()并检查。这不是 liveData 的问题。稍后我会解释,首先检查它是否工作。
标签: android android-room android-livedata