Search code examples
androidtimerobservableretrofit2rx-java2

Using rxjava timer and retrofit


I know this code is antipatterns but how can I write it correctly. Can you help me? If the web api does not respond in 2 seconds, I want to open a ProgressDialog. When you answer, close it.

getCompositeDisposable().add(mRemoteUseCase.sendData(profileInfo)
                .subscribeOn(scheduler)
                .observeOn(androidSchedulers)
                .doOnSubscribe(s ->
                {
                    mIsLoading.set(true);
                    Observable.timer(2000, TimeUnit.MILLISECONDS).take(1).subscribeOn(scheduler)
                            .observeOn(androidSchedulers).doOnNext(c -> {
                        if (mIsLoading.get() && isShowProgressDialog) {
                            progressDialog.show();
                        }
                    }).subscribe(l -> {

                    });
                })
                .doAfterTerminate(() -> {
                    mIsLoading.set(false);
                    if (progressDialog.isShowing()) {
                        progressDialog.dismiss();
                    }
                })
                .subscribe(new Consumer<RemoteResponse<UserData>>() {
                               @Override
                               public void accept(RemoteResponse<UserData> remoteResponse) throws Exception {

                                   dataManager.setProfile(profile);

                               }
                           },
                        new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) throws Exception {
                                listener.onError(throwable);

                                dialog = DialogFactory.createSimpleOkErrorDialog(context, "Error");
                                dialog.show();
                            }
                        })
        );

Solution

  • You can use two observables. The first one will use .delay() to show the progress dialog. The second will you'll use to make the request. If the request finishes before 2 seconds - cancel the first one with .dispose().

    Here's an example (it's Kotlin but you'll get the idea):

        val dialogObservable = Single.just(true)
                .observeOn(Schedulers.computation())
                .subscribeOn(AndroidSchedulers.mainThread())
                .delay(2, TimeUnit.SECONDS)
                .subscribe({
                    // show dialog
                }, {
                    // do something with the error
                })
    
        val startTime = System.currentTimeMillis()
        mRemoteUseCase.sendData(profileInfo)
                .subscribeOn(scheduler)
                .observeOn(androidSchedulers)
                .subscribe({
                    val endTime = System.currentTimeMillis()
                    if(TimeUnit.MILLISECONDS.toSeconds(endTime - startTime) <= 2){
                        dialogObservable.dispose()
                    }
    
                    // do something else
                }, {
                    // do something with the error
                })