dvdciri
dvdciri

Reputation: 451

Observable concatMap does things on the main thread for some reasons

I've got a chain of Observables and a dialog that is dismissing after everything is finished.The order is this: 1 api call get ResponseBody 2 take response body process (not ui thread) 3 other process (not ui thread)

During the first call the dialog is okay, when it comes to the second and I receive the body of the first call the dialog is blocked and it remain as is for the rest of the time.

At the end after everything is done, but I receive a warning says that "The app is doing to much work on the main thread".

I'm not doing anything on the main thread, so I don't really understand how i can unblock the dialog and keep everything on a separate thread.

showLoadingDialog();

        mZappAppApis.downloadDatabase(Token.getToken(AppConfig.TOKEN_SYNC_DOWNLOAD_DATABASE))
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .concatMap(new Func1<ResponseBody, Observable<String>>() {
                    @Override
                    public Observable<String> call(ResponseBody responseBody) {
                        return mDatabaseFileHelper.writeDatabaseToFile(responseBody);
                    }
                })
                .concatMap(new Func1<String, Observable<String>>() {
                    @Override
                    public Observable<String> call(String s) {
                        return mDatabaseFileHelper.copyDatabaseIntoZappApp();
                    }
                })
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        dismissLoadingDialog();

                        saveLocalTimestamp(timestamp);

                        flowContinueInterface.onContinueFlow();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Logger.e(e, "Error during processing new database");

                        dismissLoadingDialog();

                        flowContinueInterface.onStopFlow();
                    }

                    @Override
                    public void onNext(String result) {
                        Logger.d(result);
                    }
                });

Upvotes: 1

Views: 739

Answers (2)

Stephan
Stephan

Reputation: 16739

Move your .observeOn(AndroidSchedulers.mainThread()) above the subscribe(… call. Everything after your observeOn(… is executed on this thread. You can see this in by printing out the current thread you are on:

.subscribeOn(Schedulers.newThread())
.concatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(final String string) {
                    Log.i("Before", Thread.currentThread().toString());
                    return Observable.just(string);
                }
            })
.observeOn(AndroidSchedulers.mainThread())
.concatMap(new Func1<String, Observable<String>>() {
          @Override
          public Observable<String> call(final String string) {
                    Log.i("After", Thread.currentThread().toString());
                    return Observable.just(string);
          }
})
...

Upvotes: 1

Dave Moten
Dave Moten

Reputation: 12087

The concatMap work is happening on the main thread. You need to move the observeOn call to just above the subscribe call.

I would also move significant processing out of the subscriber into doOnCompleted and doOnError calls that are also placed before the observeOn.

Upvotes: 2

Related Questions