RxJava асинхронная задача в Android

Я пытаюсь реализовать асинхронную задачу с помощью RxJava в Android. Я попробовал следующий код и он не работает. Он выполняется в потоке пользовательского интерфейса. Я использую следующую версию RxAndroid 0.24.0.

try {
            Observable.just(someMethodWhichThrowsException())
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(s -> onMergeComplete());
        } catch (IOException e) {
            e.printStackTrace();
        }

однако для меня асинхронно работает следующее.

Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                try {
                    someMethodWhichThrowsException();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                subscriber.onCompleted();
            }
        });
        observable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe();

Я пытаюсь понять следующее: 1. В чем разница между ними? 2. Какова наилучшая практика при создании асинхронных задач?

спасибо продвижение.

2 ответов


  1. в чем разница между ними?
Observable.just(someMethodWhichThrowsException())
    .subscribeOn(Schedulers.newThread())

это эквивалентно следующему:

Object someResult = someMethodWhichThrowsException();
Observable.just(someResult)
    .subscribeOn(Schedulers.newThread())

как вы можете видеть, это делает вызов синхронного метода первым,затем передает Observable.just чтобы стать наблюдаемыми.

Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            ...
        }
    })
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe();

этот метод, однако, будет запускать код в call блок на подписку. Вы сказали, что хотите подписаться на новый поток (subscribeOn(Schedulers.newThread())), поэтому подписка происходит в новом потоке, и код, который запускается по подписке (call block) также запускается в этом потоке. Это похоже на поведение вызова Observable.defer.

  1. какова наилучшая практика при создании асинхронных задач?

Ну, это зависит от вас и вашего желаемого поведения. Иногда вы хотите, чтобы асинхронный код начал выполняться немедленно (в этом случае вы можете кэшировать его с помощью одного из операторов для этого цель.) Я бы определенно рассмотрел использование Асинхронные Utils библиотека для этого.

в других случаях вы захотите, чтобы он запускался только по подписке (что является поведением в примерах здесь) - например, если есть побочные эффекты, или если вам все равно, когда он запускается, и просто хотите использовать встроенные модули, чтобы получить что-то из потока пользовательского интерфейса. Дэн Лью упоминает это Observable.defer очень удобно для старого кода и получение его из потока пользовательского интерфейса, во время преобразования к Rx.


Использовать Async.start () from RxJava Async Utils библиотека. Это вызовет функцию, которую вы предоставляете в другом потоке.

пример:

Observable<String> observable = Async.start(new Func0<String>() {
    @Override
    public String call() {
        try {
            return someMethodWhichThrowsException();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
});

Как вы заметили, проверенные исключения должны быть обернуты в RuntimeExceptions.

Смотрите также https://github.com/ReactiveX/RxJava/wiki/Async-Operators#start