0
votes

I have the following code, which returns a lot of data in the response, so much that I get a NullPointerException when it's being loaded in the android Activity when I scroll down too fast (since not all the data has been initialized yet), no problems if I wait a second and then scroll.

I want a way to delay the subscribe part, so that the Response<GetFeedTopicsResponseBody> is entirely populated with data (none is not initialized) when I call setAdapter. I tried checking response.isSuccessful but that does not work because no problem with the response itself, just the data takes time to deserialize into Java objects from JSON. I also tried onComplete in subscribe but that does not work either.

So I want either a way in RxJava2 to have a boolean value switch to notify the following subscription once it is complete, it will subscribe.

        mGetFeedTopicsDisposable = ApiClient.getInstance()
            .doGetFeedTopicsQuery(request)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
            .subscribe((Response<GetFeedTopicsResponseBody> response) -> {
                if (response.body() != null) {
                    List<Topic> topics = response.body().getTopics();
                    if (topics != null) {
                        mBinding.fragmentTopicListRecyclerTopics.setAdapter(TopicListAdapter.getInstance(topics));
                        if (response.body().isPaginated()) {
                            mRequestBuilder.setCursor(response.body().getCursor());
                        }
                    }
                }
            }, (Throwable ex) -> {
                Log.e(TAG, ex.getMessage());
            });

The error message I specifically got was:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.models.User.getThumbnailImageUrl()' on a null object reference

where this User object is set as a field of the Topic object which is added into the list of topics retrieved with getTopics(). If I don't scroll, I don't get this NullPointerException and the thumbnail urls for the Users are loaded properly.

1
First thing comes in mind is the delay operator, did you try it? reactivex.io/documentation/operators/delay.html - y.allam
Can you post the error log? I think the issue is because you create your adapter in the response when you should create it before the call and then update the data in the adapter with the ones returned by the call - Eselfar
added error log - bycfly
delaay does not work, I tried it - bycfly
In order to delay the events you can, surprisingly, use delay operator. You tried it already and it didn't work but how exactly did you try? - lelloman

1 Answers

2
votes

Question : How do I delay RxJava2 Subscription?

Example :

I have added repeat(...) for better understanding.

io.reactivex.Observable
                    .just(new Object())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .delay(10, TimeUnit.SECONDS)
                    .repeat(2)
                    .doOnSubscribe(disposable -> Log.d("Delay Example ","Observer subscribed at : "+  DateFormat.getDateTimeInstance().format(new Date()) + " and execute after 10 seconds"))
                    .subscribe(new DefaultObserver<Object>() {
                        @Override
                        public void onNext(Object o) {
                            Log.d("Delay Example ","on Next : "+  DateFormat.getDateTimeInstance().format(new Date()));
                        }
                        @Override
                        public void onError(Throwable e) {}
                        @Override
                        public void onComplete() {
                            Log.d("Delay Example ","on Complete : "+ DateFormat.getDateTimeInstance().format(new Date()));
                        }
                    });

Output:

log

You see, on Next is called twice with 10 second delay.

Here, you can do adapter related operations in onComplete. :)

Hope this answers the question that you've asked.