我对
LiveData
的理解是,它将在数据的当前状态变化上触发观察者,而不是一系列数据的历史状态变化。
目前,我有一个
MainFragment
,它执行
Room
的写操作,来改变
非废弃的数据
, to
废弃的数据
.
我也是另一个
TrashFragment
,它观察到的是
废弃的数据
.
请考虑以下情况。
MainFragment
is the current active fragment.
TrashFragment
is not created yet.
MainFragment
added 1
废弃的数据
.
MainFragment
with
TrashFragment
.
TrashFragment
's observer will first receive
onChanged
, with 0
废弃的数据
TrashFragment
's observer will secondly receive
onChanged
, with 1
废弃的数据
出乎我意料的是,第(6)项不应该发生。
TrashFragment
应该只收到最新的
废弃的数据
, which is 1.
Here's my code:
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();
Code which deals with Room
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();
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,
).build();
return INSTANCE;
有什么办法可以防止我对同一个数据收到onChanged
两次?
我创建了一个演示项目来证明这个问题。
正如你所看到的,在我执行写操作后(点击添加废弃的笔记在MainFragment
中,当我切换到TrashFragment
时,我期望TrashFragment
中的onChanged
将只被调用一次。然而,它却被调用了两次。
演示项目可以从以下网站下载https://github.com/yccheok/live-data-problem