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

问题描述 投票:0回答:1

我实现了扩展ItemKeyedDataSource的类,并提供来自房间数据库的数据访问对象(DAO)的分页数据。我的DAO的查询方法将数据对象列表(不包含在LiveData中)传递给DataSource回调。

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

android android-architecture-components
1个回答
2
投票

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

我像这样实现了我的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实例。

© www.soinside.com 2019 - 2024. All rights reserved.