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 ответов
- в чем разница между ними?
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
.
- какова наилучшая практика при создании асинхронных задач?
Ну, это зависит от вас и вашего желаемого поведения. Иногда вы хотите, чтобы асинхронный код начал выполняться немедленно (в этом случае вы можете кэшировать его с помощью одного из операторов для этого цель.) Я бы определенно рассмотрел использование Асинхронные 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