Search code examples
androidrx-javarx-java2

I'm using a 3rd party library - How do I wrap their network call with a Single<> or RxJava Observable?


I'm trying implement MVVM using a third party SDK that makes a query to get a wallet balance. (They do not have an API endpoint only their SDK so no retrofit library use)

In my MainRepository class I'm using one of their methods that makes a Request and returns a Wallet Balance.

public Request<BigInteger> getWalletBalance(String walletAddress) {
        return thirdPartyService.getBalance(new Address(walletAddress));
}

And in my MainViewModel class I am making a request using their SDK

public void getWalletBalance(String address) {
        mainRepository.getWalletBalance(address).execute(new Callback<BigInteger>() {
            @Override
            public void onSuccess(BigInteger result) {
                walletBalanceLiveData.postValue(String.valueOf(result));

            }

            @Override
            public void onFailure(Exception exception) {
                balanceErrorLiveData.postValue("Failed to get wallet balance");
            }
        });
    }

The problem is, their method .execute() is running on the Android UI thread causing the app to freeze while making the query.

If I was using RxJava I could do something like this (In my ViewModel)...

mainRepository.getWalletBalance(address)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleObserver<BigInteger>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onSuccess(@NonNull BigInteger result) {
                        
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        
                    }
                });

But that wouldn't work because the return type in my MainRepository method above returns a Request<BigInteger>.

So my question is, is it possible to wrap that Request<BigInteger> with a RxJava class so I can cleanly implement a RxJava request with this third party library?

Or maybe there is a better or simpler solution I can do in order to make that Request on a background thread and returning the result in the ViewModel to process?


Solution

  • This may not be the cleanest solution in the world but it could work. Let the execute function block the Singles return as we know it already blocks normally.

    Single.fromCallable(()->{
            BigInteger bigIntResult = null;
               //You can take advantage of execute's blocking behavior by 
               // letting it block the callable's return.
            mainRepository.getWalletBalance(address).execute(new Callback<BigInteger>() {
                @Override
                public void onSuccess(BigInteger result) {
                    bigIntResult = result;
                }
                @Override
                public void onFailure(Exception exception) {
                      throw exception;
                }
            }
            return bigIntResult;
    })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleObserver<BigInteger>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                         // grab the disposable
                    }
                    @Override
                    public void onSuccess(@NonNull BigInteger result) {
                         // Here is the callable's return
                         walletBalanceLiveData.postValue(String.valueOf(result));
                    }
    
                    @Override
                    public void onError(@NonNull Throwable e) {
                         balanceErrorLiveData.postValue("Failed to get wallet balance");
                    }
                }
    });