Я с трудом читаю какие-то статьи, где вместо «Активити» или «Activity» написано «Активность» а вместо сабджекта «объект» или «субъект».
Без мутабельности и импрувментов можно было и обойтись в тексте, да. Но это транскрипт с записи речи, а с языка мне и не хочется их убирать, поэтому так и вышло.
Ну ладно, что уж вы) Я не приравнивал Rx к самому подходу. Конечно, это лишь одна из многих реализаций, тут я полностью с вами согласен.
Другое дело, что для Android все таки сильно чаще используется именно RxJava или RxKotlin или еще что из Rx.
Кстати, акторы и streams идут на самом деле достаточно параллельно, как мне кажется. Никто же не запрещает их вместе использовать их в одном проекте и они хорошо могут вместе работать.
Но соглашусь, что чаще говорят именно про RxJava и меньше про другие фреймворки и подходы.
На самом деле очень сложно поначалу вникнуть и понять, зачем все это нужно. Мне кажется, что некоторые люди просто ее используют, потому что это «модно», а не потому, что дает им какие-то выгоды.
Если говорить про понимание, то, возможно, саам стоит начать с лекций и видео каких-нибудь. Из довольно много и про Android и про iOS, про веб фронтенд и даже про бекенды. Там частенько бывают вещи, которые раскрывают всю суть реактивного подхода
Я соглашусь с Артемом. Дело в том, что этого не называют конкретно в вакансии, но на собеседовании многие компании, которые использую всякие новый технологии, наверняка будут рады, если вы будете знать что-нибудь связанное с Rx. Не говоря о том, что самих проектов на ней под Android становится все больше и больше.
Да, про это тоже хотел написать. Не совсем понятно, почему «корпорация добра» заставляет своих покупателей думать о проводах, их характиристиках и толщине.
Я привык, покупая телефон, получать все необходимое для его использования, а не заказывать с ebay или алиэкспресс.
Наушники, например, таковыми(необходимыми) не являются и я не против того, чтобы их не клали. Но такие вещи, как переходник с type-c на type-a в андроид мире, где повсеместно используется type-a — это не очень правильный ход, по моему мнению.
Правильно ли я понял, что в коробке кабеля type-c — type-a не предусмотрено? Не очень понятно, как подключить телефон в компьютеру и использовать его для разработки Android приложений в таком случае.
Хорошая статья, приятно читается и написана хорошо, спасибо вам.
Хотел немного порассуджать про Subject. По моему мнению они выглядят как костыль над самими потоками. Потому что под источником подразумевается обычно замкнутая система, которая сама решает, как порождать ей элементы и когда это делать. И, как и любое костыль над контрактом, сабджекты провоцируют людей чаще их (сабджектов) использовать и само их использование иногда ведет к нарушению идеологии реактивных потоков:) Безусловно, бывает, что их применение оправдано. Обычно это делается в том случае, когда по-другому источник невозможно создать или в целях оптимизации.
Когда мы говорили о задаче, я подразумевал, что мы будем создавать свой Observable, который будет эммитить объекты самостоятельно, а не делать это через сабджекты.
Например, он может эммитить дату последнего айтема, чтобы загружать с этой даты новые, или adapter.getItemCount(), чтобы эммитить сразу оффсет, по которому идти, как у вас и сделано.
Что-то типа:
public final class ScrollObservable {
public static Observable<Integer> from(final RecyclerView rv) {
return Observable.create(subscriber -> {
final RecyclerView.OnScrollListener sl = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (!subscriber.isUnsubscribed()) {
final int position = getLastVisibleItemPosition();
final int limit = getLimit();
final int updatePosition = rv.getAdapter().getItemCount() - 1 - (limit / 2);
if (position >= updatePosition) {
subscriber.onNext(rv.getAdapter().getItemCount());
}
}
}
};
rv.addOnScrollListener(sl);
subscriber.add(Subscriptions.create(() -> rv.removeOnScrollListener(sl)));
});
}
}
В этом случае получается Обсервабл, который начинает бешено эммитить айтемы при достижении определеного порога. Чтобы это происходило всего один раз, нам не надо делать подписки и отписки от сабджектов или что-то еще, просто применяем distinctUntilChanged и получаем новые оффсеты только раз:
final Observable<Integer> offsetRequestObs = ScrollObservable.from(recyclerView).distinctUntilChanged();
Соответственно в onNext мы не будем запускать новый Observable, потому что это тоже не очень круто, тк они получаются оторваны от жизненного цикла родителя. Просто делаем switchMap и потом перенаправляем на ui, где обрабатываем:
В целом это решение делает то же самое, но, как мне кажется, оно лучше поддается расширению и это полноценный Observable, с котором можно делать все, что угодно. Кроме того, имеем связанный жизненный цикл потоков, что тоже важно.
Как я и говорил выше, сабджекты обычно зло и без них очень часто можно сделать лучше и лаконичнее. Не понимаю, почему их все часто используют. Кроме того, важным фактом тут является еще то, что мы не делаем нового наследника RecyclerView, но и в вашем примере можно добиться того же.
Согласен с 7voprosov про reduce, еще хотел отметить, что в примере у вас после concatMap идет map, и по сути map не нужен, можно вставить этот геттер прямо в concatMap, убрав лишний оверхэд и сделав код более коротким и более читабельным (на вкус и цвет, разумеется).
Полностью согласен с вами. Добавлю так же, что лучше создавать несколько тредпулов с меньшим количеством тредов.
Например, тредпул с CPU_COUNT/2 для работы с сетью, такой же для выполнения рутинных задач и FixedThreadPoolExecutor на 2-3 треда для выполнения очень приоритетных задач (коих должно быть не много по задумке).
Так проще регулировать работы обсерваблов, если их становится много, а так же позволяет приоритезировать задачи. Обычно это работает неплохо.
Я говорю про запуск голосом, Вы про это же? Я не говорю, что это уникальная фича, я лишь говорю, что она есть не во всех лаунчерах и мне ее не хватает.
Без мутабельности и импрувментов можно было и обойтись в тексте, да. Но это транскрипт с записи речи, а с языка мне и не хочется их убирать, поэтому так и вышло.
Другое дело, что для Android все таки сильно чаще используется именно RxJava или RxKotlin или еще что из Rx.
Кстати, акторы и streams идут на самом деле достаточно параллельно, как мне кажется. Никто же не запрещает их вместе использовать их в одном проекте и они хорошо могут вместе работать.
Но соглашусь, что чаще говорят именно про RxJava и меньше про другие фреймворки и подходы.
Если говорить про понимание, то, возможно, саам стоит начать с лекций и видео каких-нибудь. Из довольно много и про Android и про iOS, про веб фронтенд и даже про бекенды. Там частенько бывают вещи, которые раскрывают всю суть реактивного подхода
Это прям огорчило меня.
Я привык, покупая телефон, получать все необходимое для его использования, а не заказывать с ebay или алиэкспресс.
Наушники, например, таковыми(необходимыми) не являются и я не против того, чтобы их не клали. Но такие вещи, как переходник с type-c на type-a в андроид мире, где повсеместно используется type-a — это не очень правильный ход, по моему мнению.
Правильно ли я понял, что в коробке кабеля type-c — type-a не предусмотрено? Не очень понятно, как подключить телефон в компьютеру и использовать его для разработки Android приложений в таком случае.
Кажется, что это достаточно большой косяк.
Хотел немного порассуджать про Subject. По моему мнению они выглядят как костыль над самими потоками. Потому что под источником подразумевается обычно замкнутая система, которая сама решает, как порождать ей элементы и когда это делать. И, как и любое костыль над контрактом, сабджекты провоцируют людей чаще их (сабджектов) использовать и само их использование иногда ведет к нарушению идеологии реактивных потоков:) Безусловно, бывает, что их применение оправдано. Обычно это делается в том случае, когда по-другому источник невозможно создать или в целях оптимизации.
Когда мы говорили о задаче, я подразумевал, что мы будем создавать свой Observable, который будет эммитить объекты самостоятельно, а не делать это через сабджекты.
Например, он может эммитить дату последнего айтема, чтобы загружать с этой даты новые, или adapter.getItemCount(), чтобы эммитить сразу оффсет, по которому идти, как у вас и сделано.
Что-то типа:
В этом случае получается Обсервабл, который начинает бешено эммитить айтемы при достижении определеного порога. Чтобы это происходило всего один раз, нам не надо делать подписки и отписки от сабджектов или что-то еще, просто применяем distinctUntilChanged и получаем новые оффсеты только раз:
Соответственно в onNext мы не будем запускать новый Observable, потому что это тоже не очень круто, тк они получаются оторваны от жизненного цикла родителя. Просто делаем switchMap и потом перенаправляем на ui, где обрабатываем:
В целом это решение делает то же самое, но, как мне кажется, оно лучше поддается расширению и это полноценный Observable, с котором можно делать все, что угодно. Кроме того, имеем связанный жизненный цикл потоков, что тоже важно.
Как я и говорил выше, сабджекты обычно зло и без них очень часто можно сделать лучше и лаконичнее. Не понимаю, почему их все часто используют. Кроме того, важным фактом тут является еще то, что мы не делаем нового наследника RecyclerView, но и в вашем примере можно добиться того же.
Согласен с 7voprosov про reduce, еще хотел отметить, что в примере у вас после concatMap идет map, и по сути map не нужен, можно вставить этот геттер прямо в concatMap, убрав лишний оверхэд и сделав код более коротким и более читабельным (на вкус и цвет, разумеется).
Например, тредпул с CPU_COUNT/2 для работы с сетью, такой же для выполнения рутинных задач и FixedThreadPoolExecutor на 2-3 треда для выполнения очень приоритетных задач (коих должно быть не много по задумке).
Так проще регулировать работы обсерваблов, если их становится много, а так же позволяет приоритезировать задачи. Обычно это работает неплохо.
Единственный метод, который возвращает не новый Observable, а Subscription — это метод subscribe()
Понимаю, что не так изящно, как "+", но лучше, чем явно заданная где-то вверху функция.
Как java-related разработчик не могу не заметить, что немного похоже на Scala. Или мне просто кажется и это просто веяния современности.
Тем не менее, жду не дождусь, когда на нем можно будет писать полноценные приложения.
Интересно, пол года назад точно нельзя было на стоковом киткате.