使用ItemKeyedDataSource观察Room Database表中的更改

时间:2018-02-25 20:30:42

标签: android android-architecture-components

我实现了扩展ItemKeyedDataSource的类,并提供来自会议室数据库的数据访问对象(DAO)的分页数据。我的DAO查询方法将数据对象列表(未由LiveData包裹)传递给DataSource回调。

在其包装的数据库表中发生更改后,使DataSource无效的建议方法是什么,例如,如果更改来自后台服务?如何在DAO可以生成的DataSource.Factory<Integer, T>返回参数中实现自动数据失效?

1 个答案:

答案 0 :(得分:2)

可以通过将DataSource挂钩到InvalidationTracker.Observer来实现自动InvalidationTracker失效。 您可以从getInvalidationTracker()获取InvalidationTracker个实例。

我像这样实施了InvalidationTracker.Observer

public class DataSourceTableObserver extends InvalidationTracker.Observer {

    private DataSource dataSource;

    public DataSourceTableObserver(@NonNull String tableName) {
        super(tableName);
    }

    @Override
    public void onInvalidated(@NonNull Set<String> tables) {
       if (dataSource != null) dataSource.invalidate();
    }

    public void setCurrentDataSource(DataSource source) {
        dataSource = source;
    }

}

我正在我的内部DataSource.Factory课程中使用它:

public static class Factory implements DataSource.Factory<TvProgram, TvProgram> {

    private Context appContext;
    private DataSourceTableObserver observer;
    private InvalidationTracker tracker;
    private int channelId;

    public Factory(Context context, int channelId) {
        appContext = context.getApplicationContext();

        observer = new DataSourceTableObserver(AppDatabase.PROGRAMS_TABLE);
        tracker = AppDatabase.getInstance(appContext).getInvalidationTracker();
        tracker.addObserver(observer);

        this.channelId = channelId;
    }

    @Override
    public DataSource<TvProgram, TvProgram> create() {
        EpgDataSource epgDataSource = new EpgDataSource(appContext, channelId);
        observer.setCurrentDataSource(epgDataSource);
        return epgDataSource;
    }

    public void cleanUp() {
        tracker.removeObserver(observer);
        observer = null;
    }

}

DataSourceTableObserver使DataSource无效时,Factory内部类会使用最新数据创建新的DataSource实例。