我对 LiveData
的理解是,它会触发观察者对当前数据状态的改变,而不是一系列历史数据状态的改变。
目前,我有一个 MainFragment
,它执行 Room
写操作,将 未经处理的数据改为 垃圾数据。
我还有另一个 TrashFragment
,它观察到 垃圾数据。
考虑下面的场景。
MainFragment
是当前活动的片段。 TrashFragment
尚未创建。MainFragment
增加了1个 垃圾数据。TrashFragment
代替 MainFragment
。TrashFragment
的观察者将首先接收 onChanged
,0 垃圾数据TrashFragment
的观察者将第二次接收到 onChanged
和 垃圾数据出乎我意料的是,第(6)项不应该发生。TrashFragment
应该只接收最新的 垃圾数据,即1。
这是我的密码
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);
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);
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
相同的数据?
我创建了一个演示项目来演示这个问题。
如您所见,在 MainFragment
中执行写操作(单击 添加废纸条按钮)之后,当我切换到 TrashFragment
时,我预计 TrashFragment
中的 onChanged
只会被调用一次。然而,它被调用了两次。