5

私は以下のコードでそれを調べようとしていますが、なぜ新しいデータでデータベースにデータを取り込んでも、これが私の活動ののonCreateメソッドにルーム - LiveDataオブザーバはデータベースが更新されたときにトリガしません

を入れている:

shiftsViewModel = ViewModelProviders.of(this).get(ShiftsViewModel.class); 
shiftsViewModel 
      .getShifts() 
      .observe(this, this::populateAdapter); 

これはpopulateAdapter方法である:

private void populateAdapter(@NonNull final List<Shift> shifts){ 

    recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(shifts)); 
} 

私はまた、データベース(私がやりRxJavaを使用を移入する次のコードを持っていますルームはそのコードをメインスレッド外で呼び出さなければならないのでIOスレッドで作業する):

@Override 
public Observable<List<Shift>> persistShifts(@NonNull final List<Shift> shifts){ 

    return Observable.fromCallable(() -> { 

     appDatabase.getShiftDao().insertAll(shifts); 
     return shifts; 
    }) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()); 
} 

私の問題は、私がシフトビューモデルを観察し始めた後に、persistShiftsを呼び出すときに発生します。私は、私のオブザーバー(LiveData)が新たに加えられたすべてのシフトを引き起こすと期待します。オブザーバがトリガされたことが分かりますが、代わりに空のシフトリストが返されます。それを「仕事」にする唯一の方法は、私がアクティビティを離れて(したがって、現在のViewModelを破壊する)、再び入力することです。今回は、viewModelのLiveDataによって、予想どおり以前に保持されたすべてのシフトが表示されます。ここで

は、コードの残りの部分である:

@Entity 
public class Shift{ 

    @PrimaryKey 
    private long id; 

    private String start; 
    private String end; 
    private String startLatitude; 
    private String startLongitude; 
    private String endLatitude; 
    private String endLongitude; 
    private String image; 
    ... 

DAO:

@Dao 
public interface ShiftDAO { 

    @Query("SELECT * FROM shift") 
    LiveData<List<Shift>> getAll(); 

    @Query("SELECT * FROM shift WHERE id = :id") 
    LiveData<Shift> getShiftById(long id); 

    @Insert(onConflict = OnConflictStrategy.REPLACE) 
    void insertAll(List<Shift> shifts); 
} 

のViewModel:

public class ShiftsViewModel extends AndroidViewModel{ 

    private final ISQLDatabase sqlDatabase; 

    private MutableLiveData<Shift> currentShift; 
    private LiveData<List<Shift>> shifts; 
    private boolean firstTimeCreated; 


    public ShiftsViewModel(final Application application){ 

     super(application); 

     this.sqlDatabase = ((ThisApplication) application).getSQLDatabase(); 
     this.firstTimeCreated = true; 
    } 

    public MutableLiveData<Shift> getCurrentlySelectedShift(){ 

     if(currentShift == null){ 
     currentShift = new MutableLiveData<>(); 
     } 

     return currentShift; 
    } 

    public LiveData<List<Shift>> getShifts() { 

     if(shifts == null){ 
     shifts = sqlDatabase.queryAllShifts(); 
     } 

    return shifts; 
    } 

    public void setCurrentlySelectedShift(final Shift shift){ 

     currentShift = getCurrentlySelectedShift(); 

     currentShift.setValue(shift); 
    } 

    public boolean isFirstTimeCreated(){ 
     return firstTimeCreated; 
    } 

    public void alreadyUsed(){ 
     firstTimeCreated = false; 
    } 
} 

なぜ私は私がに固執シフトのリストを取得しておりませんすぐにコールバックを観察()しますか?

+0

ViewModelコードとgetAll()の呼び出し場所を表示できますか? – Lyla

+0

提供されたものはどんなものでも見栄えは良いですが、上記の質問に続きますViewModel –

+0

@Lyla ViewModelコードがリクエストごとに追加されました。 – Tiago

答えて

20

私はDaoの異なるインスタンスを持つことによって引き起こされたDagger 2、データを更新/挿入するためのもの、および観測用のLiveDataを提供する別のインスタンスで同様の問題がありました。 Daoのシングルトンインスタンスを管理するDaggerを設定すると、アクティビティ内のLiveDataを監視しながら、バックグラウンド(私の場合はサービス)でデータを挿入でき、onChange()コールバックが呼び出されます。

Daoのインスタンスになるのは、データを挿入/更新し、観測のためにLiveDataを提供するインスタンスと同じでなければなりません。

+0

はい、ライブアップデートを取得するには、すべての操作で 'Dao'のインスタンスが同じであることを確認する必要があります。 –

+0

私は同じ問題が発生しました。あなたのアンカーに感謝して、私は私の 'RoomDatabase'プロビジョニングメソッドで' @ Singleton'を忘れてしまったことがわかりました。私は、私の場合、2つの異なるDaoが同じテーブルを照会していることを付け加えたいと思います.1つは古典的なエンティティに関連し、もう1つは2つの埋め込みエンティティを持つラッパークラスに属し、結合クエリを再現します。オブジェクトは異なりますが、 'LiveData'は正しく更新されるため、シングルトンでなければならないのは' RoomDatabase'でしょう。 – devrocca

+0

ケーキの玉ねぎ。 –

関連する問題