es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Estoy usando una librería de terceros – ¿Cómo envuelvo su llamada de red con un Single<> o un Observable de RxJava?

Estoy intentando implementar MVVM usando un SDK de terceros que realiza una consulta para obtener el saldo de una billetera. (No tienen un punto final de API, solo su SDK, por lo que no se utiliza la biblioteca Retrofit)

En mi clase “MainRepository”, estoy utilizando uno de sus métodos que realiza una solicitud y devuelve el saldo de la billetera.

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

Y en mi clase “MainViewModel”, estoy realizando una solicitud utilizando su 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("No se pudo obtener el saldo de la billetera");
        }
    });
}

El problema es que su método “.execute()” se está ejecutando en el hilo de interfaz de usuario de Android, lo que hace que la aplicación se bloquee mientras realiza la consulta.

Si estuviera utilizando RxJava, podría hacer algo como esto (en mi 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) {

        }
    });

Pero eso no funcionaría porque el tipo de retorno en mi método “MainRepository” anterior devuelve una “Request“.

Entonces, mi pregunta es, ¿es posible envolver esa “Request” con una clase de RxJava para poder implementar de manera limpia una solicitud de RxJava con esta biblioteca de terceros?

¿O tal vez hay una solución mejor o más simple que pueda hacer para realizar esa solicitud en un hilo de fondo y devolver el resultado en el ViewModel para procesarlo?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible envolver la clase Request<biginteger> con una clase de RxJava. Una forma de hacerlo es crear un Observable personalizado de RxJava que llame al método Request.execute() en un hilo de fondo y devuelva el resultado en el hilo principal utilizando los métodos Observable.fromCallable() y Observable.observeOn(). Aquí tienes un ejemplo de implementación:

    En tu clase MainRepository, crea un nuevo método que devuelva un Observable:

    public Observable<biginteger> getWalletBalanceObservable(String walletAddress) {
        return Observable.fromCallable(() -> {
            return thirdPartyService.getBalance(new Address(walletAddress)).execute();
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .toObservable();
    }
    

    Este método crea un Observable que envuelve la llamada al método Request.execute() dentro del operador fromCallable(). El método subscribeOn() especifica el grupo de hilos en el que se ejecutará la operación. En este caso, será en un hilo de entrada/salida en segundo plano. El método observeOn() especifica el hilo en el que se devolverá el resultado. En este caso, será el hilo principal de Android. Por último, se llama al método toObservable() para convertir el resultado en un Observable.

    En tu clase MainViewModel, ahora puedes utilizar este nuevo método para realizar la solicitud utilizando RxJava:

    public void getWalletBalance(String address) {
        mainRepository.getWalletBalanceObservable(address)
            .subscribe(new SingleObserver<biginteger>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {
    
                }
    
                @Override
                public void onSuccess(@NonNull BigInteger result) {
                    walletBalanceLiveData.postValue(String.valueOf(result));
                }
    
                @Override
                public void onError(@NonNull Throwable e) {
                    balanceErrorLiveData.postValue("Error al obtener el saldo del monedero");
                }
            });
    }
    

    Este código se suscribe al nuevo Observable devuelto por el método getWalletBalanceObservable() y procesa el resultado en el hilo principal utilizando el método onSuccess(). El método onError() se llama si la solicitud falla.

    Al usar esta implementación personalizada de RxJava, ahora puedes realizar la solicitud en un hilo de fondo y evitar que se congele el hilo de la interfaz de usuario.

Comments are closed.