Ma compréhension sur LiveData
, c'est que, il sera le déclencheur de l'observateur sur l'état actuel de changement de données, et non pas une série historique de modification de l'état des données.
Actuellement, j'ai un MainFragment
, qui effectuent Room
opération d'écriture, de changer non saccagé des données, à la corbeille de données.
J'ai aussi un autre TrashFragment
, qui observe à la corbeille de données.
Envisagez le scénario suivant.
- Il y a actuellement 0 saccagé des données.
-
MainFragment
est active fragment.TrashFragment
n'est pas encore créé. -
MainFragment
ajouté 1 saccagé des données. - Maintenant, il y a 1 saccagé données
- Nous utilisons la navigation tiroir, remplacer,
MainFragment
avecTrashFragment
. -
TrashFragment
s'observateur va d'abord recevoironChanged
, 0 mis à la corbeille de données - Encore une fois,
TrashFragment
s'observateur va ensuite recevoironChanged
, avec 1 saccagé données
Ce qui est hors de mon espoir est que, l'élément (6) ne devrait pas arriver. TrashFragment
ne doit recevoir les dernières saccagé des données, qui est de 1.
Voici mes codes
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 qui traite avec Salle de
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;
}
}
Une idée de comment je peux les empêcher de recevoir des onChanged
deux fois, pour une même donnée?
Démo
J'ai créé un projet de démonstration pour illustrer ce problème.
Comme vous pouvez le voir, après je effectuer une opération d'écriture (Cliquez sur AJOUTER à la CORBEILLE NOTE bouton) en MainFragment
, lorsque je passe à TrashFragment
, j'attends onChanged
en TrashFragment
ne sera appelée qu'une seule fois. Toutefois, il est appelé deux fois.
Projet de démonstration peut être téléchargée à partir de https://github.com/yccheok/live-data-problem