我正在尝试从文件系统读取文件,更新房间数据库并最终更新UI。这似乎是一个特别简单的任务,但是我在正确使用Android和RxJava Scheduler方面遇到了困难。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
this.loadingTextView = this.findViewById(R.id.tvLoading);
this.subscription = Observable.just(0)
.subscribeOn(Schedulers.io())
.flatMap(ignore -> engine.checkEngineRequirements())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(ignore-> Log.e("glog", "Received on thread " + Thread.currentThread().getName()),
throwable -> Log.e("glog", "[WelcomeActivity.onCreate()]:" + throwable.getMessage()),
() -> {
this.loadingTextView.setText("Loaded");
Log.d("glog", "[WelcomeActivity] Launching new activity");
Intent intent = new Intent(this, PlayGameActivity.class);
this.startActivity(intent);
}
);
}
在checkEngineRequirements中,我正在从文件加载文件并填充房间数据库:
private Observable<Long> checkEngineRequirements() {
return new OfflineDataLoad().load(this.context)
.observeOn(Schedulers.io())
.flatMap(data -> this.dataRepository.addData(data));
}
public Observable<String> load(Context context) {
return Observable.create(emitter -> {
try {
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(
context.getAssets().open(DB_FILE_NAME), "UTF-8"));
(...)
while (lineAvailabe) {
emitter.onNext(line)
}
emitter.onComplete();
}
catch (Exception e) {
emitter.onError(e);
}
});
}
我的数据源(存储库)实现如下:
@Override
public Observable<Long> addData(Data newDataItem) {
return Observable.fromCallable(() -> this.dataDao.insertData(newDataItem));
}
问题在于永远不会调用onComplete事件。知道我在做什么错吗?
答案 0 :(得分:1)
基于评论:
对序列进行故障排除的一般方法是使用doOnXXXX
运算符并记录各种事件。
在这种情况下,所描述的流程并不意味着任何无限序列(因为这在Room查询中非常常见),并且没有做任何特别复杂的事情。因此,剩下的就是存储的subscription
变量,以及当从主线程上的onCreate
内部启动时,代码的主要部分在后台运行并且最终可能会返回的事实。再次进入主线程。
这给UI提供了充足的时间来销毁UI,并销毁了上述subscription
。当然,可以肯定的是,将doOnDispose()
应用于日志记录时应尽可能接近最终用户,并且应该已经证明确实是这种情况:
this.subscription = Observable.just(0)
.subscribeOn(Schedulers.io())
.flatMap(ignore -> engine.checkEngineRequirements())
.observeOn(AndroidSchedulers.mainThread())
// v---------------------------------v-----------------------------------v----
.doOnDispose(() -> Log.e("glog", "[WelcomeActivity.onCreate()]: Disposed"))
// ^---------------------------------^-----------------------------------^--
.subscribe(ignore-> Log.e("glog", "Received on thread "
+ Thread.currentThread().getName()),
throwable -> Log.e("glog", "[WelcomeActivity.onCreate()]:"
+ throwable.getMessage()),
() -> {
this.loadingTextView.setText("Loaded");
Log.d("glog", "[WelcomeActivity] Launching new activity");
Intent intent = new Intent(this, PlayGameActivity.class);
this.startActivity(intent);
}
);