LiveData の値が明らかに変更されていなくても、DB で行が更新されるたびに、Dao によって返される LiveData がそのオブザーバーを呼び出すことがわかりました。
次の例のような状況を考えてみましょう:
エンティティの例
@Entity
public class User {
public long id;
public String name;
// example for other variables
public Date lastActiveDateTime;
}
例のダオ
@Dao
public interface UserDao {
// I am only interested in the user name
@Query("SELECT name From User")
LiveData<List<String>> getAllNamesOfUser();
@Update(onConflict = OnConflictStrategy.REPLACE)
void updateUser(User user);
}
バックグラウンドスレッドのどこかに
UserDao userDao = //.... getting the dao
User user = // obtain from dao....
user.lastActiveDateTime = new Date(); // no change to user.name
userDao.updateUser(user);
UIのどこかに
// omitted ViewModel for simplicity
userDao.getAllNamesOfUser().observe(this, new Observer<List<String>> {
@Override
public void onChanged(@Nullable List<String> userNames) {
// this will be called whenever the background thread called updateUser.
// If user.name is not changed, it will be called with userNames
// with the same value again and again when lastActiveDateTime changed.
}
});
この例では、UI はユーザー名のみに関心があるため、LiveData のクエリには名前フィールドのみが含まれます。ただし、他のフィールドのみが更新されたとしても、observer.onChanged は Dao Update で呼び出されます。(実際、User エンティティに変更を加えずに UserDao.updateUser を呼び出しても、observer.onChanged は引き続き呼び出されます)
これは Room の Dao LiveData の設計された動作ですか? 選択したフィールドが更新されたときにのみオブザーバーが呼び出されるように、これを回避できる可能性はありますか?
編集: 次のクエリを使用して、コメントの KuLdip PaTel が示唆するように lastActiveDateTime 値を更新するように変更しました。ユーザー名の LiveData のオブザーバーは引き続き呼び出されます。
@Query("UPDATE User set lastActiveDateTime = :lastActiveDateTime where id = :id")
void updateLastActiveDateTime(Date lastActiveDateTime, int id);