简体   繁体   中英

How to get the value from Single Observable in rxjava?

private void getAccount(String accountName,String password) {
    Log.i("ACCOUNT_", "any message"); //this is executed
    Single.fromCallable(() -> {
        String account = accountName;
        Log.i("ACCOUNT_", account); //not executed
        return account;
    }).flatMap((accountName) ->{
        return accountRepository.findAccount(accountName);
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe((List<Account> accounts) -> {
                Account accountModel = accounts.get(0);//not executed
                Log.i("ACCOUNT_", accountModel.getName());//not executed
            },throwable -> {
               Log.i("ACCOUNT_", "BAD EROR");//not executed
      });

}

I have updated the code commenting which parts are not executed when I call getAcount() method. What could be the reason?

I am almost sure that this is related with execution on AndroidSchedulers.mainThread() , on which you observe your Single . Please make sure that this thread is running and is not terminating before your code executes.

Unfortunately, I have no Android environment in my hand and your code is not complete. But as a demonstration I rewrote your code with mock methods for a standard Java. Looks like this:

package com.dpopov.rxjava.stackoverflow;

import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.SingleSource;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

import java.util.Collections;
import java.util.List;
import java.util.Set;

public class ObservableNotExecuting {

    public static void main(String[] args) throws InterruptedException {
        getAccount("accName", "accPass");

        Thread.sleep(5000);
    }

    private static void getAccount(String accountName, String password) {
        System.out.println("ACCOUNT_" + "any message"); // this is executed

        Single.fromCallable(() -> {
            String account = accountName;
            System.out.println("ACCOUNT_" + account); // not executed
            return account;
        })
                .flatMap((Function<String, SingleSource<?>>) ObservableNotExecuting::findAccount)
                .subscribeOn(Schedulers.io())
//                .observeOn(Schedulers.mainThread())
//                .observeOn(Schedulers.mainThread())
                .subscribe(
                        accounts -> {
//                        accountObject -> {
//                            Account accountModel = accounts.get(0); // not executed
//                            System.out.println("ACCOUNT_" + accounts.name); // not executed
                            final Account account = ((List<Account>) accounts).get(0);
                            System.out.println("account: " + account.name);
                        },
                        throwable -> {
                            System.out.println("ACCOUNT_" + "BAD ERROR"); // not executed
                        }
                );
    }

    private static SingleSource<List<Account>> findAccount(final String accountName) {
        return new Single<List<Account>>() {
            @Override
            protected void subscribeActual(final SingleObserver<? super List<Account>> observer) {
                final Account account = new Account(accountName);
                final List<Account> accountsList = Collections.singletonList(account);
                observer.onSuccess(accountsList);
            }
        };
    }

    static class Account {
        public final String name;

        public Account(final String name) {
            this.name = name;
        }
    }
}

You can try to execute this locally. Main point is: if you remove Thread.sleep line in #main , only first line is written to the output, since the main thread is terminated right after #getAccount has returned, before any Observable logic starts to execute.

Therefore, look how your Android UI thread is running when executing your RxJava code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM