Статья поверхностная. Зачатки BDUI были давно, только слово такого не было. Пример из головы: форма отправки платежа в банке. Тот случай когда нерационально разрабатывать отдельную нативную форму на все виды платежей, проще создать конструктор.
Мне кажется у двух ваших подопытных больше общего, чем различий. Реклама, реклама и еще раз реклама. Все маркетплейсы сейчас стараются показать как можно больше айтемов пользователю. В результате они превратились в помойку.
Вы используете альфа версию, но для продакшен кода нужно веское обоснование. Неясно в чем отличие версии 2.1.0-alpha03 от стабильной, можно привести ссылку на release notes. Room хорошо дружит с RxJava, а с недавних пор и с корутинами. Преимущество над курсорами очевидно, но ничего не сказано про другие библиотеки (StorIO, SQLDelight).
Вы предлагает тестировать миграции на устройстве, используя базу данных в памяти. Не пробовали ли вы запустить Room на локальной JVM под роболектриком?
У вас переменная release_store_password доступна во всем build.gradle. Почему бы не вынести ее в signingConfigs.release[debug]. Ключ подписи отладочной версии тоже должен оставаться постоянным, но отличаться от релизной.
Вы считаете безопасно хранить my_key.jks в репозитории? Если злоумышленник получит свою копию ключа остается надеятся только на стойкость алгоритма шифрования. Я бы не стал подсаживаться на переменную github.run_number. Что делать если придется мигрировать на GitLab/TeamCity, или когда у внешнего сервиса собьется нумерация сборок? Вместо того, чтобы вручную докручивать образ ubuntu-latest, можно взять один из готовых от CircleCi. Совсем необязательно выносить работу keystore.properties на уровень всего скрипта сборки. Я предпочитаю иметь ограниченную область, в которой можно обратиться к RELEASE_STORE_PASSWORD. В репозитории на GitHub есть раздел с релизами, было бы круто автоматом отправлять туда артефакты сборки, в том числе от proguard/R8.
Статья отличная, к месту бы пришелся кейс с оператором share, разделение цепочек не практикуете?
Я активно использую Rx для синхронизации изменений из базы данных. Большую часть кода занимает обработка ошибок. Если это не простейшая ошибка сети, а что-то разумное, то нужно предпринять меры для достижения согласованности локальной базы данных. Для этого в обработчике ошибок от сервера нужно иметь ссылку на модель, которая не была успешно отправлена.
С Rx это выливается во вложенные лямбды или выделенные реализации onErrorResumeNext и отдельный класс исключение, чтобы передать модель. Вроде этого
class SyncCoherenceError(val model: SyncModel): Exception()
fun sync(bundle: SyncModel): Single<SuccessModel> {
return api.sync(bundle)
.onErrorResumeNext { error ->
if (error is CoherenceError) {
Single.error(SyncCoherenceError(bundle))
} Single.error(error)
}
}
В обработчике нужно "распаковать" исключение, снова onErrorResumeNext. Никак не доходят руки проверить облегчат ли задачу корутины с им императивным стилем.
Метод subscribe, который возвращает Diposable, помечен аннотацией CheckReturn, ничто не мешает линтером проверять, действительно ли результат таких методов был передан куда-то дальше. Студия навязчиво подсвечивает такие ситуации. Я бы предложил переопределить для пары DisposableContainer и Disposable инфиксную операторную функцию plus и "складывать" ресурс с контейнером.
Интересная статья, не так давно решал с коллегой достаточной редкий кейс разбора json. На входе массив объектов, структуру которых мы заранее не знаем. Но знаем какие поля и каких типов в них могут быть. Таким образом можно декларативно описать платежную форму, а вот статически описать модель данных уже не получится. Мы не нашли в Decodable способа получить условно JsonRecord, по элементам которого можно было бы вручную итерироваться. Может это реализовано в какой-нибудь сторонней библиотеке?
В Android R наконец-то завезли то, о чем я говорил в своем комментарии выше. А именно вменяемую возможность узнать высоту клавиатуры. Клавиатура вмешивается в работу приложения, сдвигает интерфейс. Теперь я с большей силой настаиваю на том, что вариант из статьи (которым я, однако, пользуюсь) является костылем.
Разделяю скептицизм автора по отношению к BottomSheetBehavior, он применим только в простых сценариях. Под капотом он использует простой компонент ViewDragHelper, но во вложенной прокрутке мне не удалось разобраться. BottomSheetBehavior задизайнен таким образом, что перехватывает все жесты внутри корневой вью. Поэтому нельзя ограничить drag-and-drop только TextView, он будет срабатывать на всем списке.
Вы выбрали неудачный пример для демонстрации реактивного программирования. Оно хорошо подходит для асинхронных long-running операций, числа Фибоначчи проще рассчитывать по-требованию. Писать собственный Publisher для вычисления простой последовательности выглядит оверинжинирингом. Для существующих источников (Future, Just, Record) представлено много операторов, с их помощью можно построить самые разные цепочки. Например такую
import Combine
let _ = (0...9)
.publisher
.scan ((1, 0), { source, _ -> (Int, Int) in
let (first, second) = source
return (second, first + second)
})
.sink { (first, _) in
print(first)
}
Что будете делать, когда у разных событий возникнут одинаковые аргументы? Расширять иерархию MyFragmentNavigation абстрактным классом? Кажется тут самое место sealed class. Вы пишите, что получился аналог Rx-BehaviorSubject-a, но RxJava хороша своей расширяемостью. Для ее существует куча операторов, можно и свой какой-нибудь написать. Если речь про взаимодействие Presenter и View не проще использовать Moxy? Там организованы похожие стратегии, которые можно расширять.
Отличная статья, давно хочу подтянуть питон. Жаль, что в статью не включены такие разделы как generic (дженерики) и FP (элементы функционального программирования).
От таких примеров больше вреда, чем пользы. Он не идут дальше наброска приложения из пары кнопок и кучи неучтенных кейсов. Вызывать методы какого-то класса из фреймворка это лишь маленькая часть работы при разработке приложения. Даже для разработки диктофона нужно знать как обрабатывать разрешения. Код из репозитория автора отличается от приведенного в статье, но там этот кейс тоже не учтен. В статье профильного блога на хабре стоит рассматривать более комплексные задачи, а не лажать в очевидных местах.
Вы правы. Я забыл про настройку android.builder.sdkDownload. Главное, что бы скачивание компонент не происходило при каждой сборке. Может образоваться очередь из сборок. Я сторонник разделять зависимости самого приложения (classpath) и sdk. В build.gradle зависимости изменяются чаще, чем версия платформы.
Статья поверхностная. Зачатки BDUI были давно, только слово такого не было. Пример из головы: форма отправки платежа в банке. Тот случай когда нерационально разрабатывать отдельную нативную форму на все виды платежей, проще создать конструктор.
Мне кажется у двух ваших подопытных больше общего, чем различий. Реклама, реклама и еще раз реклама. Все маркетплейсы сейчас стараются показать как можно больше айтемов пользователю. В результате они превратились в помойку.
Из статьи следует что в Nexus вы отправляете только apk файл. Не думали так же поступать с маппингом R8?
Вы используете альфа версию, но для продакшен кода нужно веское обоснование. Неясно в чем отличие версии
2.1.0-alpha03
от стабильной, можно привести ссылку на release notes. Room хорошо дружит с RxJava, а с недавних пор и с корутинами. Преимущество над курсорами очевидно, но ничего не сказано про другие библиотеки (StorIO, SQLDelight).Вы предлагает тестировать миграции на устройстве, используя базу данных в памяти. Не пробовали ли вы запустить Room на локальной JVM под роболектриком?
Когда на хабре появится черный список для неинтересных компаний первым делом добавлю туда Otus.
У вас переменная
release_store_password
доступна во всемbuild.gradle
. Почему бы не вынести ее в signingConfigs.release[debug]. Ключ подписи отладочной версии тоже должен оставаться постоянным, но отличаться от релизной.Вы считаете безопасно хранить my_key.jks в репозитории? Если злоумышленник получит свою копию ключа остается надеятся только на стойкость алгоритма шифрования. Я бы не стал подсаживаться на переменную github.run_number. Что делать если придется мигрировать на GitLab/TeamCity, или когда у внешнего сервиса собьется нумерация сборок? Вместо того, чтобы вручную докручивать образ ubuntu-latest, можно взять один из готовых от CircleCi. Совсем необязательно выносить работу keystore.properties на уровень всего скрипта сборки. Я предпочитаю иметь ограниченную область, в которой можно обратиться к
RELEASE_STORE_PASSWORD
. В репозитории на GitHub есть раздел с релизами, было бы круто автоматом отправлять туда артефакты сборки, в том числе от proguard/R8.Я правильно понял, что вы практикуете релиз еще не оттестированного QA функционала в продакшен, если он закрыт feature flag?
Статья отличная, к месту бы пришелся кейс с оператором
share
, разделение цепочек не практикуете?Я активно использую Rx для синхронизации изменений из базы данных. Большую часть кода занимает обработка ошибок. Если это не простейшая ошибка сети, а что-то разумное, то нужно предпринять меры для достижения согласованности локальной базы данных. Для этого в обработчике ошибок от сервера нужно иметь ссылку на модель, которая не была успешно отправлена.
С Rx это выливается во вложенные лямбды или выделенные реализации
onErrorResumeNext
и отдельный класс исключение, чтобы передать модель. Вроде этогоВ обработчике нужно "распаковать" исключение, снова
onErrorResumeNext
. Никак не доходят руки проверить облегчат ли задачу корутины с им императивным стилем.Метод
subscribe
, который возвращаетDiposable
, помечен аннотациейCheckReturn
, ничто не мешает линтером проверять, действительно ли результат таких методов был передан куда-то дальше. Студия навязчиво подсвечивает такие ситуации. Я бы предложил переопределить для парыDisposableContainer
иDisposable
инфиксную операторную функциюplus
и "складывать" ресурс с контейнером.Спасибо, долго не могли дойти до этого способа.
Интересная статья, не так давно решал с коллегой достаточной редкий кейс разбора json. На входе массив объектов, структуру которых мы заранее не знаем. Но знаем какие поля и каких типов в них могут быть. Таким образом можно декларативно описать платежную форму, а вот статически описать модель данных уже не получится. Мы не нашли в Decodable способа получить условно JsonRecord, по элементам которого можно было бы вручную итерироваться. Может это реализовано в какой-нибудь сторонней библиотеке?
В Android R наконец-то завезли то, о чем я говорил в своем комментарии выше. А именно вменяемую возможность узнать высоту клавиатуры. Клавиатура вмешивается в работу приложения, сдвигает интерфейс. Теперь я с большей силой настаиваю на том, что вариант из статьи (которым я, однако, пользуюсь) является костылем.
Открыл статью чтобы узнать наконец какая связь между клавиатурой и inset, а увидел только старый костыль с расчетом высоты.
Разделяю скептицизм автора по отношению к BottomSheetBehavior, он применим только в простых сценариях. Под капотом он использует простой компонент ViewDragHelper, но во вложенной прокрутке мне не удалось разобраться. BottomSheetBehavior задизайнен таким образом, что перехватывает все жесты внутри корневой вью. Поэтому нельзя ограничить drag-and-drop только TextView, он будет срабатывать на всем списке.
Вы выбрали неудачный пример для демонстрации реактивного программирования. Оно хорошо подходит для асинхронных long-running операций, числа Фибоначчи проще рассчитывать по-требованию. Писать собственный Publisher для вычисления простой последовательности выглядит оверинжинирингом. Для существующих источников (Future, Just, Record) представлено много операторов, с их помощью можно построить самые разные цепочки. Например такую
Что будете делать, когда у разных событий возникнут одинаковые аргументы? Расширять иерархию
MyFragmentNavigation
абстрактным классом? Кажется тут самое место sealed class. Вы пишите, что получился аналог Rx-BehaviorSubject-a, но RxJava хороша своей расширяемостью. Для ее существует куча операторов, можно и свой какой-нибудь написать. Если речь про взаимодействие Presenter и View не проще использовать Moxy? Там организованы похожие стратегии, которые можно расширять.Отличная статья, давно хочу подтянуть питон. Жаль, что в статью не включены такие разделы как generic (дженерики) и FP (элементы функционального программирования).
От таких примеров больше вреда, чем пользы. Он не идут дальше наброска приложения из пары кнопок и кучи неучтенных кейсов. Вызывать методы какого-то класса из фреймворка это лишь маленькая часть работы при разработке приложения. Даже для разработки диктофона нужно знать как обрабатывать разрешения. Код из репозитория автора отличается от приведенного в статье, но там этот кейс тоже не учтен. В статье профильного блога на хабре стоит рассматривать более комплексные задачи, а не лажать в очевидных местах.
Вы правы. Я забыл про настройку
android.builder.sdkDownload
. Главное, что бы скачивание компонент не происходило при каждой сборке. Может образоваться очередь из сборок. Я сторонник разделять зависимости самого приложения (classpath) и sdk. Вbuild.gradle
зависимости изменяются чаще, чем версия платформы.