Я обнаружил, что LiveData, возвращаемый 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);
Где-то в интерфейсе
// 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.
}
});
В этом примере пользовательский интерфейс интересует только имя пользователя, поэтому запрос LiveData включает только поле имени. Однако Observer.onChanged будет по-прежнему вызываться при обновлении Dao, даже если обновляются только другие поля. (На самом деле, если я не внесу никаких изменений в сущность User и вызову UserDao.updateUser, по-прежнему будет вызываться Observer.onChanged)
Это спроектированное поведение Dao LiveData в комнате? Есть ли шанс, что я смогу обойти это, так что наблюдатель будет вызываться только при обновлении выбранного поля?
Изменение: я изменил, чтобы использовать следующий запрос для обновления значения lastActiveDateTime, как KuLdip PaTel в комментарии предлагают. Наблюдатель LiveData имени пользователя по-прежнему вызывается.
@Query("UPDATE User set lastActiveDateTime = :lastActiveDateTime where id = :id")
void updateLastActiveDateTime(Date lastActiveDateTime, int id);