我的TrackerConnectionManager
类中有以下方法
@Override
public Observable<TrackerFile> deleteFiles(final List<TrackerFile> trackerFiles) {
Observable<TrackerFile> deleteFilesObservable = Observable.create(new ObservableOnSubscribe<TrackerFile>() {
@Override
public void subscribe(@NonNull ObservableEmitter<TrackerFile> emitter) throws Exception {
Log.i(TAG, "deleteFiles() --> subscribe() --> trackerFiles.size(): " + trackerFiles.size());
for (TrackerFile file : trackerFiles) {
Log.i(TAG, "deleteFiles() --> subscribe() --> emitter.onNext(trackerConnectionAPI.deleteFile()): " + file.getFileName());
final boolean success = trackerConnectionAPI.deleteFile((char) file.getFileId());
// Error mitigation in case that TrackerConnectionAPI returns false
if (success) {
emitter.onNext(file);
} else {
Log.w(TAG, "trackerConnectionAPI.deleteFile() return false for file: " + file);
}
}
Log.i(TAG, "deleteFiles() --> subscribe() --> emitter.onComplete()");
emitter.onComplete();
}
});
,这应调用 cleanTracker 方法:
private void startTrackerRoutine() {
Disposable disposable = trackerConnectionManager.iterateFiles()
.subscribe(trackerFiles -> {
if (trackerFiles.isEmpty()) {
Log.d(TAG, "startTrackerRoutine() --> no files on Tracker --> disconnect & startNoSessionFoundFragment");
disconnectFromTracker();
activity.startNoSessionFoundFragment();
return;
}
Log.i(TAG, "startTrackerRoutine() --> Tracker has " + trackerFiles.size() + " files to process.");
// TODO: THIS CALL NEEDS TO BE BLOCKING; else we have a RACE CONDITION with the actual transfer of files
cleanTracker(trackerFiles);
ArrayList<TrackerFile> newSessions = SessionFileHelper.findNewSessions(trackerFiles, tracker.getId(), realm);
Log.i(TAG, "startTrackerRoutine() --> found newSessions: " + newSessions);
if (newSessions.isEmpty()) {
Log.d(TAG, "startTrackerRoutine() --> NO NEW Sessions --> disconnect & startNoSessionFoundFragment");
disconnectFromTracker();
activity.startNoSessionFoundFragment();
} else {
activity.startTransferSessionFragment(newSessions);
}
}, throwable -> {
Log.e(TAG, "startTrackerRoutine() --> ERROR in trackerConnectionManager.iterateFiles() --> disconnectFromTracker()", throwable);
disconnectFromTracker();
if (throwable instanceof ForeignSessionException) {
fragment.showForeignTrackerDialog();
} else {
fragment.showConnectionFailedDialog();
}
});
activeRequests.add(disposable);
}
现在我想知道如何调用此deleteFiles()
方法并等待其完成->调用emitter.onComplete()
。
我尝试过:
private void cleanTracker(final List<TrackerFile> trackerFiles) {
final List<TrackerFile> filesToDelete = SessionFileHelper.findNonSessionFiles(trackerFiles);
Log.i(TAG, "cleanTracker() --> found " + filesToDelete.size() + " files to be deleted");
Disposable disposable = trackerConnectionManager.deleteFiles(filesToDelete)
.subscribe(trackerFile -> {
if (trackerFile != null) {
Log.d(TAG, "cleanTracker() --> successfully deleted: " + trackerFile);
} else {
Log.w(TAG, "cleanTracker() --> FAILED to delete a file");
}
}, throwable -> {
Log.e(TAG, "cleanTracker() --> ERROR while deleting files: " + filesToDelete);
});
Log.d(TAG, "cleanTracker() --> activeRequests.add(disposable)");
activeRequests.add(disposable);
}
但是它并没有帮助我,因为直到所有文件都被删除并且其他命令弄乱了我的套接字连接时,它才真正等待/阻塞。
答案 0 :(得分:1)
等待子流完成是concat*
操作员的工作。您的案件可以通过concatMap
解决:
private void startTrackerRoutine() {
Disposable disposable = trackerConnectionManager.iterateFiles()
.observeOn(Schedulers.io())
.concatMap(trackerFiles -> {
if (trackerFiles.isEmpty()) {
Log.d(TAG, "startTrackerRoutine() --> no files on Tracker --> disconnect & startNoSessionFoundFragment");
disconnectFromTracker();
activity.startNoSessionFoundFragment();
return Observable.empty();
}
Log.i(TAG, "startTrackerRoutine() --> Tracker has " + trackerFiles.size() + " files to process.");
return cleanTrackerFlow(trackerFiles);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(trackerFiles -> {
ArrayList<TrackerFile> newSessions = SessionFileHelper.findNewSessions(trackerFiles, tracker.getId(), realm);
Log.i(TAG, "startTrackerRoutine() --> found newSessions: " + newSessions);
if (newSessions.isEmpty()) {
Log.d(TAG, "startTrackerRoutine() --> NO NEW Sessions --> disconnect & startNoSessionFoundFragment");
disconnectFromTracker();
activity.startNoSessionFoundFragment();
} else {
activity.startTransferSessionFragment(newSessions);
}
}, throwable -> {
Log.e(TAG, "startTrackerRoutine() --> ERROR in trackerConnectionManager.iterateFiles() --> disconnectFromTracker()", throwable);
disconnectFromTracker();
if (throwable instanceof ForeignSessionException) {
fragment.showForeignTrackerDialog();
} else {
fragment.showConnectionFailedDialog();
}
});
activeRequests.add(disposable);
}
private Observable<List<TrackerFile>> cleanTracker(final List<TrackerFile> trackerFiles) {
final List<TrackerFile> filesToDelete = SessionFileHelper.findNonSessionFiles(trackerFiles);
Log.i(TAG, "cleanTracker() --> found " + filesToDelete.size() + " files to be deleted");
return trackerConnectionManager.deleteFiles(filesToDelete)
.doOnNext(trackerFile -> {
Log.d(TAG, "cleanTracker() --> successfully deleted: " + trackerFile);
})
.doOnError(throwable -> {
Log.e(TAG, "cleanTracker() --> ERROR while deleting files: " + filesToDelete);
})
.ignoreElements()
.andThen(Observable.just(trackerFiles));
}