我现在正致力于从网络获取数据的任务,在UI上显示,并将数据保存到本地数据库以供日后使用。目前我做的如下:
//Cloud loading
Observable<MyModel> loadDataFromCloud();
//Database
Observable<MyModel> saveDataToDisk(MyModel myModel);
//Load data
loadDataFromCloud()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Func1<MyModel, Observable<MyModel>>() {
@Override
public Observable<MyModel> call(MyModel myModel) {
return saveDataToDisk(myModel);
}
})
.subscribe(new Subscriber<MyModel>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
//exception handling
}
@Override
public void onNext(MyModel myModel) {
//bind myModel to UI
}
});
这种方法工作正常,但由于数据模型变得越来越复杂,数据库变得越来越大,因此它不再高效,因为所有数据库事务现在都在主线程上执行,UI需要等到完成交易以获得数据。
我现在正在改变这种新方法:
//A Singleton
Scheduler scheduler = Schedulers.from(Executors.newSingleThreadExecutor());
//Load data
loadDataFromCloud()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Func1<MyModel, Observable<MyModel>>() {
@Override
public Observable<MyModel> call(MyModel myModel) {
try {
//bind myModel to UI
return Observable.just(s);
} catch(Exception e) {
return Observable.error(e)
}
}
})
.observeOn(scheduler)
.flatMap(new Func1<MyModel, Observable<MyModel>>() {
@Override
public Observable<MyModel> call(MyModel myModel) {
return saveDataToDisk(myModel);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<MyModel>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
//exception handling
}
@Override
public void onNext(MyModel myModel) {
//do nothing
}
});
我使用Schedulers.from(Executors.newSingleThreadExecutor())
来确保所有数据库事务都是线程安全的。
我有一些问题:
Schedulers.from(Executors.newSingleThreadExecutor())
确保所有数据库事务都是线程安全的是正确的方法吗?onNext()
无所事事似乎是不明智的我已经搜索了一段时间并收到了一些像this one这样的文章,但他们没有直接解决我的问题。
答案 0 :(得分:1)
首先,首先,你在主线程上进行IO操作,这是一个不好的做法,在android中它可以导致anr。
Scheduler
,否则您将为每个订阅此可观察对象创建新线程。但是,有些奇怪的是,因为DB操作通常是线程安全的。 saveDataToDisk()
并行而不等待它,因此您可以使用doOnNext
运算符在不同的可观察对象上启动保存操作(您不需要#39; t关心其结果)而不遵守它的结果。 总而言之,你应该这样:
loadDataFromCloud()
.doOnNext(data - > saveDataToDisk().subscribeOn(Schedulers.io()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> //uodate your ui)
Dan Lew的帖子是一个很好的例子,你应该按照那里的例子。