Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使房间DAO返回LiveData<;光标>;_Android_Android Cursor_Android Room_Android Livedata - Fatal编程技术网

Android 使房间DAO返回LiveData<;光标>;

Android 使房间DAO返回LiveData<;光标>;,android,android-cursor,android-room,android-livedata,Android,Android Cursor,Android Room,Android Livedata,你知道如何让房间DAO返回LiveData 我需要从数据库请求很多对象。 由于内存问题,我负担不起沉重的对象列表,我需要一个光标。 当然,数据可以更新,发生时需要通知我。 因此LiveData应该是一个好的解决方案 但是,当我编译时: @Dao public interface FooDao { @Query("SELECT * FROM foo") LiveData<Cursor> getFoo(); } @Dao 公共接口FooDao{ @查询(“从foo

你知道如何让房间DAO返回
LiveData


我需要从数据库请求很多对象。
由于内存问题,我负担不起沉重的对象列表,我需要一个光标。
当然,数据可以更新,发生时需要通知我。
因此
LiveData
应该是一个好的解决方案

但是,当我编译时:

@Dao
public interface FooDao {

    @Query("SELECT * FROM foo")
    LiveData<Cursor> getFoo();

}
@Dao
公共接口FooDao{
@查询(“从foo中选择*)
LiveData getFoo();
}
安卓工作室对我说:
错误:(22,22)错误:不确定如何将游标转换为此方法的返回类型


嗯。。。请不要告诉我,我们无法使用光标获取数据更新通知:/

感谢评论中的@pskink,以下是我的解决方案:

public class DbLiveData<T>
        extends MutableLiveData<T> {

    public interface DataLoader<T> {

        T loadData();

    }

    @NonNull
    private final InvalidationTracker.Observer mDatabaseObserver;

    @NonNull
    private DataLoader<T> mDataLoader;

    @NonNull
    private final Executor mExecutor;

    public DbLiveData(@NonNull String[] tables, @NonNull Executor executor, @NonNull DataLoader<T> dataLoader) {
        mExecutor = executor;
        mDataLoader = dataLoader;
        mDatabaseObserver = new InvalidationTracker.Observer(tables) {
            @Override
            public void onInvalidated(@NonNull Set<String> tables) {
                loadData();
            }
        };
        loadData();
    }

    @Override
    protected void onActive() {
        super.onActive();
        DB.get() // I get my DB from a Service Locator
                .getInvalidationTracker()
                .addObserver(mDatabaseObserver);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        DB.get() // I get my DB from a Service Locator
                .getInvalidationTracker()
                .removeObserver(mDatabaseObserver);
    }

    private void loadData() {
        mExecutor.execute(
                () -> postValue(mDataLoader.loadData())
        );
    }

}

如果使用Room2.x,则可以使用RoomDatabase的实例

RoomDatabase appDatabase;
...

public LiveData<Cursor> getCursorLiveData(){
    return appDatabase.getInvalidationTracker().createLiveData(new String[]{"table1","table2"}, true, ()->{
       Cursor cursor = ...;
       return cursor;
    }
}
RoomDatabase-appDatabase;
...
公共LiveData getCursorLiveData(){
返回appDatabase.GetInvalizationTracker().createLiveData(新字符串[]{“table1”,“table2”},true,()->{
游标=。。。;
返回光标;
}
}
表1、表2为观察表。
如果您希望computeFunction(最后一个函数arg)将在事务中完成,请提供true作为第二个参数

您只能获得
游标
,而不能获得
LiveData
,但是,您需要的可以使用
MediaLiveData
(或
android.arch.lifecycle.Transformations
)不确定我是否得到了它…你能给我看一些代码吗?@commonware这取决于,
Room
返回的只是
ArrayList
,而不是任何“复杂的”
列表
实现,例如,如果
光标
包含1M个条目,这意味着它调用
add
方法一百万次-使用原始的
光标
会快得多case@CommonsWare不完全像
SQLiteCursor
扩展
AbstractWindowedCursor
那样,最多1Mb
CursorWindow
将被填满,有
房间
和大数据集,它将被填满很多次(即使你一次不需要)游标在这种情况下更好,因为它“按需”加载数据似乎我对
转换的速度太快了
,但是
RoomDatabase#GetInvalizationTracker
很可能是您想要的:在它上面调用
addObserver
,当某些表的内容发生更改时,您将随时收到通知-因此这是更新
LiveData
变量的好方法(通过调用
LiveData#setValue
方法)
RoomDatabase appDatabase;
...

public LiveData<Cursor> getCursorLiveData(){
    return appDatabase.getInvalidationTracker().createLiveData(new String[]{"table1","table2"}, true, ()->{
       Cursor cursor = ...;
       return cursor;
    }
}