Android 使房间DAO返回LiveData<;光标>;
你知道如何让房间DAO返回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
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
那样,最多1MbCursorWindow
将被填满,有房间
和大数据集,它将被填满很多次(即使你一次不需要)游标在这种情况下更好,因为它“按需”加载数据似乎我对转换的速度太快了
,但是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;
}
}