Мое понимание LiveData
заключается в том, что оно вызывает наблюдателя при текущем изменении состояния данных, а не в изменении состояния данных в истории.
В настоящее время у меня есть MainFragment
, который выполняет операцию записи в Room
, чтобы изменить не поврежденные данные, чтобы обрезать данные.
Я также еще один TrashFragment
, который наблюдает за разбитыми данными.
Рассмотрим следующий сценарий.
- В настоящее время имеются данные с обрывом.
-
MainFragment
- текущий активный фрагмент.TrashFragment
еще не создан. -
MainFragment
добавлено 1MainFragment
данные. - Теперь есть 1 поврежденные данные
- Мы используем навигационный ящик, чтобы заменить
MainFragment
наTrashFragment
. - Наблюдатель
TrashFragment
сначала получитonChanged
, с 0 поврежденными данными - Опять же, наблюдатель
TrashFragment
во второй раз получитonChanged
, с 1 поврежденными данными
То, что из моего ожидания, состоит в том, что пункт (6) не должен происходить. TrashFragment
должен получать только самые последние данные об TrashFragment
1.
Здесь мои коды
TrashFragment.java
public class TrashFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
noteViewModel = ViewModelProviders.of(getActivity()).get(NoteViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
noteViewModel.getTrashedNotesLiveData().removeObservers(this);
noteViewModel.getTrashedNotesLiveData().observe(this, notesObserver);
MainFragment.java
public class MainFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
noteViewModel = ViewModelProviders.of(getActivity()).get(NoteViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
noteViewModel.getNotesLiveData().removeObservers(this);
noteViewModel.getNotesLiveData().observe(this, notesObserver);
NoteViewModel.java
public class NoteViewModel extends ViewModel {
private final LiveData<List<Note>> notesLiveData;
private final LiveData<List<Note>> trashedNotesLiveData;
public LiveData<List<Note>> getNotesLiveData() {
return notesLiveData;
}
public LiveData<List<Note>> getTrashedNotesLiveData() {
return trashedNotesLiveData;
}
public NoteViewModel() {
notesLiveData = NoteplusRoomDatabase.instance().noteDao().getNotes();
trashedNotesLiveData = NoteplusRoomDatabase.instance().noteDao().getTrashedNotes();
}
}
Код, который касается комнаты
public enum NoteRepository {
INSTANCE;
public LiveData<List<Note>> getTrashedNotes() {
NoteDao noteDao = NoteplusRoomDatabase.instance().noteDao();
return noteDao.getTrashedNotes();
}
public LiveData<List<Note>> getNotes() {
NoteDao noteDao = NoteplusRoomDatabase.instance().noteDao();
return noteDao.getNotes();
}
}
@Dao
public abstract class NoteDao {
@Transaction
@Query("SELECT * FROM note where trashed = 0")
public abstract LiveData<List<Note>> getNotes();
@Transaction
@Query("SELECT * FROM note where trashed = 1")
public abstract LiveData<List<Note>> getTrashedNotes();
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract long insert(Note note);
}
@Database(
entities = {Note.class},
version = 1
)
public abstract class NoteplusRoomDatabase extends RoomDatabase {
private volatile static NoteplusRoomDatabase INSTANCE;
private static final String NAME = "noteplus";
public abstract NoteDao noteDao();
public static NoteplusRoomDatabase instance() {
if (INSTANCE == null) {
synchronized (NoteplusRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
NoteplusApplication.instance(),
NoteplusRoomDatabase.class,
NAME
).build();
}
}
}
return INSTANCE;
}
}
Любая идея, как я могу предотвратить получение onChanged
дважды, для одних и тех же данных?
демонстрация
Я создал демонстрационный проект, чтобы продемонстрировать эту проблему.
Как вы можете видеть, после выполнения операции записи (нажмите кнопку ADD TRASHED NOTE) в MainFragment
, когда я переключусь на TrashFragment
, я ожидаю, что onChanged
в TrashFragment
будет TrashFragment
только один раз. Однако он называется дважды.
Демо-проект можно загрузить с https://github.com/yccheok/live-data-problem