Создание Twitter splash-screen с использованием MotionLayout
#разработка #дизайн #опрос
Уже не в первый раз пишу вам о возможностях и фишках нового MotionLayout. Последний пост был связан с приложением ScrumPoker, его найдёте тут.
Сегодня ещё один крутой пример. Автор решил написать анимированный Twitter-подобный splash-screen и выбрал самый простой способ — это MotionLayout. Получилось хорошо и количество кода также впечатляет: немногим более 50 строк для MotionScene.
Ссылки на первую и вторую часть статьи тут и тут.
А вы используете MotionLayout у себя в прод-проектах?
#разработка #дизайн #опрос
Уже не в первый раз пишу вам о возможностях и фишках нового MotionLayout. Последний пост был связан с приложением ScrumPoker, его найдёте тут.
Сегодня ещё один крутой пример. Автор решил написать анимированный Twitter-подобный splash-screen и выбрал самый простой способ — это MotionLayout. Получилось хорошо и количество кода также впечатляет: немногим более 50 строк для MotionScene.
Ссылки на первую и вторую часть статьи тут и тут.
А вы используете MotionLayout у себя в прод-проектах?
Результаты конкурса Podlodka Android Crew
#конкурс
Итак, наконец пришло время опубликовать результаты конкурса, описанного тут.
В конкурсе приняло участие 55 человек, при помощи генератора случайных чисел был выбран победитель — @YakovlevAleksey, с чем я его и поздравляю 😎.
Мероприятие стартует 22 июня. Уже известно расписание первой недели, связанной с архитектурой приложений.
Ещё есть шанс присоединиться и получить огромный пласт новых знаний. Ссылка с подробностями здесь.
Видео с выбором победителя тут. До новых конкурсов!
#конкурс
Итак, наконец пришло время опубликовать результаты конкурса, описанного тут.
В конкурсе приняло участие 55 человек, при помощи генератора случайных чисел был выбран победитель — @YakovlevAleksey, с чем я его и поздравляю 😎.
Мероприятие стартует 22 июня. Уже известно расписание первой недели, связанной с архитектурой приложений.
Ещё есть шанс присоединиться и получить огромный пласт новых знаний. Ссылка с подробностями здесь.
Видео с выбором победителя тут. До новых конкурсов!
Android ViewModel. Как это работает
#статьи #разработка
Наиболее популярным решением от Google для взаимодействия между Presenter-слоем и View-слоем — это ViewModel. Самым главным преимуществом является механизм сохранения состояния при пересоздании Fragment или Activity.
И кажется, что внутри намешана какая-то магия. 😯 Но если копнуть, то внутри вы обнаружите самый обычный код, где её (магии) «почти» нет.
Копнуть и разобраться в деталях поможет эта статья.
Начиная от 2017 года, автор копается во внутренностях механизмов ViewModel и рассматривает то, как менялись подходы со временем. Интересно, что в самом начале пути, у ViewModel под капотом использовался retained fragment. 🤓
#статьи #разработка
Наиболее популярным решением от Google для взаимодействия между Presenter-слоем и View-слоем — это ViewModel. Самым главным преимуществом является механизм сохранения состояния при пересоздании Fragment или Activity.
И кажется, что внутри намешана какая-то магия. 😯 Но если копнуть, то внутри вы обнаружите самый обычный код, где её (магии) «почти» нет.
Копнуть и разобраться в деталях поможет эта статья.
Начиная от 2017 года, автор копается во внутренностях механизмов ViewModel и рассматривает то, как менялись подходы со временем. Интересно, что в самом начале пути, у ViewModel под капотом использовался retained fragment. 🤓
Друзья, я решил ввести на канале новую рубрику — тестовые задачи по Android. Подобные тесты часто бывают для отсеивания кандидатов на интервью, а также на конференциях.
Итак, начнём с простого задания! 🤓
Итак, начнём с простого задания! 🤓
Для создания фичи, вам нужно использовать структуру данных «ключ-значение».
Вы знаете, что ключом всегда будет являться int и хотите оптимизировать использование памяти.
Какую структуру данных выберите?
Вы знаете, что ключом всегда будет являться int и хотите оптимизировать использование памяти.
Какую структуру данных выберите?
Anonymous Quiz
32%
HashMap
14%
ArrayMap
4%
TreeSet
44%
SparseArray
7%
HashSet
Комментарии к квизу
#quiz
Правильных ответов не так много. Поэтому, после каждого квиза будет пост с описанием, почему правильный ответ является правильным.
• HashMap — это структура данных, которая основана на хэш-таблицах. Она реализует интерфейс Map, и это подразумевает хранение в ней пар «ключ-значение». Ключи и значения могут быть любыми типами (Object), в том числе и null (что тоже является распространённым вопросом на собеседовании). Для разрешения коллизий используется метод цепочек.
В целом, вы можете использовать эту структуру для хранения данных, где ключом является Integer. Но в задаче было уточнение — эффективное использование памяти.
• ArrayMap — это также структура данных, которая позволяет хранить пары «ключ-значение». С некоторой стороны — это более эффективная по памяти замена HashMap: тут вместо одного большого массива значений, используется два массива, где первый хранит хэши ключей в сортированном порядке, а второй — ключи и значения в соответствии с этим порядком. Коллизии решаются тут методом цепочек.
Однако, получение объекта выполняется медленнее: в отличии от HashMap, где поиск выполняется при помощи получения элемента по хэш-функции, в ArrayMap поиск элемента выполняется бинарным поиском.
Но с точки зрения эффективности памяти эта структура лучше, чем HashMap.
• SparseArray — очень похожая на ArrayMap структура. Но её главным отличием является то, что ключами в ней являются примитивные типы, которые занимают ещё меньше памяти и не выполняется операции boxing/unboxing.
С точки зрения получения объектов, результат похож на ArrayMap. Но эта структура наиболее эффективна по памяти, когда вашими ключами является тип int.
У неё также есть «братья»: SparseLongArray, SparseIntArray, SparseBooleanArray, где ключами являются соотвествующие примитивы.
• HashSet и TreeSet вовсе не созданы для того, чтобы хранить пары «ключ-значение».
В целом, если ваша задача состоит в хранении небольшого количества элементов (<1000) или у вас не много операций поиска элементов, то стоит присмотреться к альтернативам HashMap. Пара классных и коротких видео про эти структуры тут и тут.
Как вам вообще тема с квизами? Продолжаем?
#quiz
Правильных ответов не так много. Поэтому, после каждого квиза будет пост с описанием, почему правильный ответ является правильным.
• HashMap — это структура данных, которая основана на хэш-таблицах. Она реализует интерфейс Map, и это подразумевает хранение в ней пар «ключ-значение». Ключи и значения могут быть любыми типами (Object), в том числе и null (что тоже является распространённым вопросом на собеседовании). Для разрешения коллизий используется метод цепочек.
В целом, вы можете использовать эту структуру для хранения данных, где ключом является Integer. Но в задаче было уточнение — эффективное использование памяти.
• ArrayMap — это также структура данных, которая позволяет хранить пары «ключ-значение». С некоторой стороны — это более эффективная по памяти замена HashMap: тут вместо одного большого массива значений, используется два массива, где первый хранит хэши ключей в сортированном порядке, а второй — ключи и значения в соответствии с этим порядком. Коллизии решаются тут методом цепочек.
Однако, получение объекта выполняется медленнее: в отличии от HashMap, где поиск выполняется при помощи получения элемента по хэш-функции, в ArrayMap поиск элемента выполняется бинарным поиском.
Но с точки зрения эффективности памяти эта структура лучше, чем HashMap.
• SparseArray — очень похожая на ArrayMap структура. Но её главным отличием является то, что ключами в ней являются примитивные типы, которые занимают ещё меньше памяти и не выполняется операции boxing/unboxing.
С точки зрения получения объектов, результат похож на ArrayMap. Но эта структура наиболее эффективна по памяти, когда вашими ключами является тип int.
У неё также есть «братья»: SparseLongArray, SparseIntArray, SparseBooleanArray, где ключами являются соотвествующие примитивы.
• HashSet и TreeSet вовсе не созданы для того, чтобы хранить пары «ключ-значение».
В целом, если ваша задача состоит в хранении небольшого количества элементов (<1000) или у вас не много операций поиска элементов, то стоит присмотреться к альтернативам HashMap. Пара классных и коротких видео про эти структуры тут и тут.
Как вам вообще тема с квизами? Продолжаем?
Store от Dropbox
#библиотека
Есть такое мнение, что единственное чем занимаются разработчики мобильных приложений — это выводят на экран то, что приходит с сервера и красят View.
Что же, в этом мнении есть небольшая доля правды, но согласитесь, что сегодняшние приложения — это не тонкий и простой клиент, а полноценное приложение, которое должно работать при любых условиях на множестве девайсах.
Есть приложения, которым для работы обязательно нужен Интернет и без него они превращаются в «тыкву» (или заглушку с сообщением об отсутствии сети). Но если ваше приложение должно работать без сети, то вам как разработчику нужно реализовывать кэш. А в этом может помочь библиотека от Dropbox, которая называется Store.
По факту, это надстройка над источником данных, которая ответственна за получение и кэширование конкретного типа данных. Когда вы создаете Store, вы предоставляете ему
Например:
Библиотека написана на Kotlin, работает с Room, SQLDelight и Realm базами данных. А тут можно почитать немного подробнее о её использовании.
#библиотека
Есть такое мнение, что единственное чем занимаются разработчики мобильных приложений — это выводят на экран то, что приходит с сервера и красят View.
Что же, в этом мнении есть небольшая доля правды, но согласитесь, что сегодняшние приложения — это не тонкий и простой клиент, а полноценное приложение, которое должно работать при любых условиях на множестве девайсах.
Есть приложения, которым для работы обязательно нужен Интернет и без него они превращаются в «тыкву» (или заглушку с сообщением об отсутствии сети). Но если ваше приложение должно работать без сети, то вам как разработчику нужно реализовывать кэш. А в этом может помочь библиотека от Dropbox, которая называется Store.
По факту, это надстройка над источником данных, которая ответственна за получение и кэширование конкретного типа данных. Когда вы создаете Store, вы предоставляете ему
Fetcher — функцию, которая определяет, как данные будут выбираться по сети. Например:
StoreBuilder
.from(
fetcher = Fetcher.of { api.fetchSubreddit(it, "10").data.children.map(::toPosts) },
sourceOfTruth = SourceOfTruth.of(
reader = db.postDao()::loadPosts,
writer = db.postDao()::insertPosts,
delete = db.postDao()::clearFeed,
deleteAll = db.postDao()::clearAllFeeds
)
).build()
Библиотека написана на Kotlin, работает с Room, SQLDelight и Realm базами данных. А тут можно почитать немного подробнее о её использовании.
Комментарии к квизу
#квиз
Знание из последнего квиза таит в себе подводные камни.
Большинство ответило верно: действительно вернётся 2. Но было много ответов 1 (в первый раз ответил именно так)
Все исключения в Kotlin являются наследниками класса Throwable. У каждого исключения есть сообщение, стек, а также причина, по которой это исключение было вызвано.
Соответсвенно, в нашем блоке try появляется исключение, дальше мы переходим в catch, где ловим это исключение. И блок finally выполнится вне зависимости от того, было вызвано исключение или нет. Поэтому, верный ответ 2.
Однако, есть любопытный момент. Если вы используете try как выражение:
То результатом выполнения будет 1. Для меня это было открытием, спасибо бдительным подписчикам @dakarkaret и @amihusb за то, что указали на эту особенность👍.
В документации написано, что при использовании expression (выражения) возвращаемое значение является либо последним выражением в блоке try, либо последним выражением в блоке catch (или блоках) и содержимое блока finally не влияет на результат выражения.
Ссылка на документацию тут.
Будьте аккуратны, когда пишите подобный код!
#квиз
Знание из последнего квиза таит в себе подводные камни.
Большинство ответило верно: действительно вернётся 2. Но было много ответов 1 (в первый раз ответил именно так)
Все исключения в Kotlin являются наследниками класса Throwable. У каждого исключения есть сообщение, стек, а также причина, по которой это исключение было вызвано.
Соответсвенно, в нашем блоке try появляется исключение, дальше мы переходим в catch, где ловим это исключение. И блок finally выполнится вне зависимости от того, было вызвано исключение или нет. Поэтому, верный ответ 2.
Однако, есть любопытный момент. Если вы используете try как выражение:
fun value(): Int =
try {
throw UnsupportedOperationException()
0
}
catch (e: Exception) {
1
}
finally {
2
}
То результатом выполнения будет 1. Для меня это было открытием, спасибо бдительным подписчикам @dakarkaret и @amihusb за то, что указали на эту особенность👍.
В документации написано, что при использовании expression (выражения) возвращаемое значение является либо последним выражением в блоке try, либо последним выражением в блоке catch (или блоках) и содержимое блока finally не влияет на результат выражения.
Ссылка на документацию тут.
Будьте аккуратны, когда пишите подобный код!
Темы или стили?
#разработка #статьи
В Android существует система стилей, которую многие разработчики используют некорректно.
Например, мы часто пренебрегаем именованием цветов и у нас в проектах появляется много оттенков одного и того же цвета: gray, graydark, graylight. Со временем туда могут добавится ещё и graylighter и graydarker.
Подобная ситауция часто возникает от неверного взаимодействия с дизайнерами и может здорово подпортить ситуацию в тот момент, когда добавляется поддержка темной темы.
Также многие из нас неверно истолковывают понимание того, что значит «тема» и «стиль» в приложении. И хотя оба имеют одинаковый синтаксис с тегом
По сути, стиль — это коллекция атрибутов View. Можно представить, что это Map<attrubute, resourse>, которая применяется для View.
Набор атрибутов может быть разный для каждой из View, и каждый из них можно применить в xml файле как параметр для View. Он применяется только для конкретной View, и не применяется для его детей.
Стиль служит для того, чтобы уменьшить количество кода. Очень удобно менять какой-то атрибут для всех View, имеющие одинаковый стиль.
По опыту скажу, что важно следить за атрибутами, которые вы пишите. Например, не стоит писать атрибуты, которые специфичны для использования View в конкретном layout, такие как ширина, высота и вес. Это чревато тем, что вы будете переопределять эти параметры напрямую в layout, а это уже противоречие в использовании стилей. Поэтому, если вы делаете так — это первый сигнал того, что лучше сделать новый стиль на основе существующего или писать эти атрибуты напрямую в layout.
Тема — это также коллекция атрибутов, но в отличии от стиля — она не имеет специальных свойств для конкретной View. Она применяется более широко и влияет на какую-то часть приложения или всё приложение. Поэтому, вы можете использовать её для любых компонентов, у которых есть
Тема нужна для для более гибкой настройки компонентов вашего экрана: можно ссылаться на атрибуты темы и в зависимости от них приложение будет выглядеть иначе.
Классная статья, рассказывающая об отличиях стиля и темы тут.
Сейчас как раз буду заниматься рефакторингом стилей в своём приложении, обязательно поделяюсь с вами опытом и сложностями, с которыми пришлось столкнуться😎.
#разработка #статьи
В Android существует система стилей, которую многие разработчики используют некорректно.
Например, мы часто пренебрегаем именованием цветов и у нас в проектах появляется много оттенков одного и того же цвета: gray, graydark, graylight. Со временем туда могут добавится ещё и graylighter и graydarker.
Подобная ситауция часто возникает от неверного взаимодействия с дизайнерами и может здорово подпортить ситуацию в тот момент, когда добавляется поддержка темной темы.
Также многие из нас неверно истолковывают понимание того, что значит «тема» и «стиль» в приложении. И хотя оба имеют одинаковый синтаксис с тегом
<style>, они значат разное в приложении. По сути, стиль — это коллекция атрибутов View. Можно представить, что это Map<attrubute, resourse>, которая применяется для View.
Набор атрибутов может быть разный для каждой из View, и каждый из них можно применить в xml файле как параметр для View. Он применяется только для конкретной View, и не применяется для его детей.
Стиль служит для того, чтобы уменьшить количество кода. Очень удобно менять какой-то атрибут для всех View, имеющие одинаковый стиль.
По опыту скажу, что важно следить за атрибутами, которые вы пишите. Например, не стоит писать атрибуты, которые специфичны для использования View в конкретном layout, такие как ширина, высота и вес. Это чревато тем, что вы будете переопределять эти параметры напрямую в layout, а это уже противоречие в использовании стилей. Поэтому, если вы делаете так — это первый сигнал того, что лучше сделать новый стиль на основе существующего или писать эти атрибуты напрямую в layout.
Тема — это также коллекция атрибутов, но в отличии от стиля — она не имеет специальных свойств для конкретной View. Она применяется более широко и влияет на какую-то часть приложения или всё приложение. Поэтому, вы можете использовать её для любых компонентов, у которых есть
Context, Activity, Fragment, ViewGroup или View. Тема нужна для для более гибкой настройки компонентов вашего экрана: можно ссылаться на атрибуты темы и в зависимости от них приложение будет выглядеть иначе.
Классная статья, рассказывающая об отличиях стиля и темы тут.
Сейчас как раз буду заниматься рефакторингом стилей в своём приложении, обязательно поделяюсь с вами опытом и сложностями, с которыми пришлось столкнуться😎.
Splitties
#библиотека
Думаю, что многие из тех, кто пишет на Kotlin, согласятся, что при помощи него можно значительно уменьшить количество кода, если сравнивать с Java. Безусловно это польза. В одной презентации увидел фразу, которая звучит как «Less code — less bugs», где есть доля истины.
Помочь в уменьшении кода может коллекция библиотек Splitties. По сути, это набор extention-функций, которые уменьшают число boilerplate кода. Основная часть методов сделана под Android, но разработчики уже написали часть из них и под multiplatform. Особенно радует то, что в проект не нужно тянуть всю библиотеку целиком — можно выбрать только те модули, которые нужны.
Список модулей впечатляет: это и работа с
Но хочу предостеречь: наличие модулей не отменяет того факта, что нам необходимо изучать библиотеку прежде чем тянуть её в проект. Но в любом случае библиотека интересная и её стоит рассмотреть, как минимум с точки зрения нетипичных решений и функций.
#библиотека
Думаю, что многие из тех, кто пишет на Kotlin, согласятся, что при помощи него можно значительно уменьшить количество кода, если сравнивать с Java. Безусловно это польза. В одной презентации увидел фразу, которая звучит как «Less code — less bugs», где есть доля истины.
Помочь в уменьшении кода может коллекция библиотек Splitties. По сути, это набор extention-функций, которые уменьшают число boilerplate кода. Основная часть методов сделана под Android, но разработчики уже написали часть из них и под multiplatform. Особенно радует то, что в проект не нужно тянуть всю библиотеку целиком — можно выбрать только те модули, которые нужны.
Список модулей впечатляет: это и работа с
Activity, с Alert Dialog, Permissions, Views. А кроме этого, есть собственный View DSL, немного напоминающий декларативный UI. Но хочу предостеречь: наличие модулей не отменяет того факта, что нам необходимо изучать библиотеку прежде чем тянуть её в проект. Но в любом случае библиотека интересная и её стоит рассмотреть, как минимум с точки зрения нетипичных решений и функций.
Забытое искусство написания конструкторов
#статьи #разработка
В идеальном мире код разработчика становится лучше день ото дня: то, что мы написали 10 лет назад должно быть лучше того, что мы писали 15 лет назад. Уверен, что в большинстве случаев это именно так.
Сейчас у нас с каждым днём становится всё больше и больше инструментов для разработки, больше «best practises» и современных языков программирования.
Но мы живём в не идеальном мире и часто забываем о некоторых практиках, которых стоит придерживаться. Одна из них — это написание конструкторов.
Конструкторы с большим количеством параметров нарушают принцип единой ответственности: ваш класс делает слишком много одновременно. Максимальное рекомендуемое количество параметров, передаваемое в конструктор — 4. Звучит нереально, учитывая, например, конструкторы Presenter. Автор описывает такой пример:
Если бы мы использовали Koin, то код стал бы похож на следующее:
Безусловно, это затрудняет понимание инициализации, и тут лучше использовать именование параметров. Но вернёмся к тому, как уменьшить количество параметров.
• выделите общие зависимости
Посмотрев на код, мы можем увидеть общую группу
Всё это можно объединить одним интерфейсом:
• используйте фасады
В тех случаях, когда обёртка интерфейсом не помогает, мы можем сделать фасад, спрятав туда похожие классы.
В нашем примере подобными являются классы, ответственные за аналитику:
Попробуем скрыть их в фасад:
• используйте use case
Ещё одним полезным советом является использование use case. Например, у нас есть несколько репозиториев, ответственных за работу профиля. Мы можем сделать из них один класс:
Важно помнить, что количество параметров конструктора — это не серебряная пуля, а только одна из метрик вашего кода. Поэтому, не пытайтесь усложнить ваш код только для того, чтобы уменьшить число параметров. 😎
#статьи #разработка
В идеальном мире код разработчика становится лучше день ото дня: то, что мы написали 10 лет назад должно быть лучше того, что мы писали 15 лет назад. Уверен, что в большинстве случаев это именно так.
Сейчас у нас с каждым днём становится всё больше и больше инструментов для разработки, больше «best practises» и современных языков программирования.
Но мы живём в не идеальном мире и часто забываем о некоторых практиках, которых стоит придерживаться. Одна из них — это написание конструкторов.
Конструкторы с большим количеством параметров нарушают принцип единой ответственности: ваш класс делает слишком много одновременно. Максимальное рекомендуемое количество параметров, передаваемое в конструктор — 4. Звучит нереально, учитывая, например, конструкторы Presenter. Автор описывает такой пример:
class ProfilePresenter@Injectconstructor( @MainThreadScheduler private val mainScheduler: Scheduler, @IOScheduler private val ioScheduler: Scheduler, private val profileApi: ProfileApi, private val userRepository: UserRepository, private val analytics: Analytics, private val errorReporter: ErrorReporter private val referrerTracker: ReferrerTracker, private val shareTracker: ShareTracker, private val tracksRepository: TracksRepository, private val playlistRepository: PlaylistRepository)Если бы мы использовали Koin, то код стал бы похож на следующее:
ProfilePresenter(get(), get(), get(), get(), get(), get(), get(), get(), get(), get())Безусловно, это затрудняет понимание инициализации, и тут лучше использовать именование параметров. Но вернёмся к тому, как уменьшить количество параметров.
• выделите общие зависимости
Посмотрев на код, мы можем увидеть общую группу
Scheduler:@MainThreadScheduler private val mainScheduler: Scheduler,
@IOScheduler private val ioScheduler: Scheduler,Всё это можно объединить одним интерфейсом:
interface RxSchedulers {
val io: Scheduler
val computation: Scheduler
val main: Scheduler
}• используйте фасады
В тех случаях, когда обёртка интерфейсом не помогает, мы можем сделать фасад, спрятав туда похожие классы.
В нашем примере подобными являются классы, ответственные за аналитику:
private val analytics: Analytics,private val referrerTracker: ReferrerTracker,private val shareTracker: ShareTrackerПопробуем скрыть их в фасад:
class ProfileTracker( private val analytics: Analytics, private val referrerTracker: ReferrerTracker, private val shareTracker: ShareTracker fun trackProfileOpened(referrer: String) = referrerTracker.profileOpened(referrer) fun trackProfileShared() = shareTracker.profileShared()}• используйте use case
Ещё одним полезным советом является использование use case. Например, у нас есть несколько репозиториев, ответственных за работу профиля. Мы можем сделать из них один класс:
class ProfileUseCase( private val userRepository: UserRepository, private val tracksRepository: TracksRepository, private val playlistRepository: PlaylistRepository,)Важно помнить, что количество параметров конструктора — это не серебряная пуля, а только одна из метрик вашего кода. Поэтому, не пытайтесь усложнить ваш код только для того, чтобы уменьшить число параметров. 😎
Расширение возможностей Android Studio
Продуктивность в написании кода — важная часть работы программиста. И её улучшить можно не только за счет библиотек, но и с помощью плагинов IDE.
Уже сегодня можно послушать о том, как писать плагины самостоятельно. На примере, спикер расскажет как написать свой плагин для генерации кода, который сэкономит много времени при работе с
Спикер — Павел Стрельченко — Android разработчик в компании hh.ru, занимается поддержкой основных приложений и разрабатывает внутренние инструменты для улучшения работы своей команды.
Подключайтесь к стриму сегодня, в 20:00 по Москве тут.
Продуктивность в написании кода — важная часть работы программиста. И её улучшить можно не только за счет библиотек, но и с помощью плагинов IDE.
Уже сегодня можно послушать о том, как писать плагины самостоятельно. На примере, спикер расскажет как написать свой плагин для генерации кода, который сэкономит много времени при работе с
ViewModel + Dagger.Спикер — Павел Стрельченко — Android разработчик в компании hh.ru, занимается поддержкой основных приложений и разрабатывает внутренние инструменты для улучшения работы своей команды.
Подключайтесь к стриму сегодня, в 20:00 по Москве тут.
YouTube
Расширение возможностей Android Studio
#AndroidBroadcast #AndroidStudio #Plugin
Улучшить продуктивность можно не только за счет библиотек, но и с помощью плагинов IDE, а как написать легко свой расскажем в выпуске.
Гость выпуска Павел Стрельченко - Android разработчик в компании hh.ru, занимается…
Улучшить продуктивность можно не только за счет библиотек, но и с помощью плагинов IDE, а как написать легко свой расскажем в выпуске.
Гость выпуска Павел Стрельченко - Android разработчик в компании hh.ru, занимается…
А вот и свежий #квиз на внимательность.
Он также больше подходит как тест на собеседование. И честнее решать его без помощи ввода в среду разработки 😉.
Он также больше подходит как тест на собеседование. И честнее решать его без помощи ввода в среду разработки 😉.
Всем привет!
С самого начала ведения этого канала, я не рассказывал о том, кто я, где работаю и чем занимаюсь, я не связывал канал с собой. Мне кажется, что это неправильно, особенно когда на канале уже больше 5000 человек. Так давайте же исправим это! 😊
Меня зовут Александр Горшков, и я автор этого канала. Уже больше 5 лет я работаю Android-разработчиком из которых последние 2 года – удалённо. Мне очень нравится этот формат работы, так как он позволяет удачно планировать своё время и много путешествовать, чем я собственно и пользуюсь.
Сейчас моя работа связана с проектом в сфере агрономии, где наша команда оцифровывает жизнь одного из крупнейших российских холдингов, делая жизнь и работу агрономов проще.
Кроме этого, я организатор GDG сообщества у себя в городе Брянск. Об этом сообществе вы не раз читали у меня на канале.
Мне всегда можно написать в личные сообщения @al_gorshkov.
Ваш фидбек нереально заряжает писать новые посты и делать «движухи». Если вдруг у вас есть какие-то идеи для канала или вам не хватает какой-то информации, связанной с Android — вы всегда можете написать мне об этом.
Возможно, кому-то интересно, чем я живу вне канала, поэтому вот ссылка на мой Instagram: https://www.instagram.com/al.gorshkoov
Спасибо что вы здесь!
До новых постов! 😎
С самого начала ведения этого канала, я не рассказывал о том, кто я, где работаю и чем занимаюсь, я не связывал канал с собой. Мне кажется, что это неправильно, особенно когда на канале уже больше 5000 человек. Так давайте же исправим это! 😊
Меня зовут Александр Горшков, и я автор этого канала. Уже больше 5 лет я работаю Android-разработчиком из которых последние 2 года – удалённо. Мне очень нравится этот формат работы, так как он позволяет удачно планировать своё время и много путешествовать, чем я собственно и пользуюсь.
Сейчас моя работа связана с проектом в сфере агрономии, где наша команда оцифровывает жизнь одного из крупнейших российских холдингов, делая жизнь и работу агрономов проще.
Кроме этого, я организатор GDG сообщества у себя в городе Брянск. Об этом сообществе вы не раз читали у меня на канале.
Мне всегда можно написать в личные сообщения @al_gorshkov.
Ваш фидбек нереально заряжает писать новые посты и делать «движухи». Если вдруг у вас есть какие-то идеи для канала или вам не хватает какой-то информации, связанной с Android — вы всегда можете написать мне об этом.
Возможно, кому-то интересно, чем я живу вне канала, поэтому вот ссылка на мой Instagram: https://www.instagram.com/al.gorshkoov
Спасибо что вы здесь!
До новых постов! 😎
Single click в Android
#разработка #статьи #опрос
Казалось бы, что может быть проще, чем сделать клик на кнопку. Используй стандартный
Опытные разработчики сталкивались с какими-то задвоенными действиями в приложении. Например, два запроса в сеть вместо одного. Часто причиной подобного поведения является именно стандартный ClickListener.
Решения может быть два:
• блокировка кнопки до появления какой-то реакции или ответа;
• добавление небольшой задержки при нажатии на кнопку.
Любопытно, что аннотация
Но сегодня, когда основная масса разработчиков использует Kotlin synthetics или View Binding, мы забываем про этот «хак».
Автор в статье напоминает об этой фиче и рассказывает, как просто использовать его, совмещая с extension-функциями Kotlin. Получилось довольно удобно, и теперь можно делать:
вместо стандартного клика.
Кто считает, что клик с задержкой — это костыль?
#разработка #статьи #опрос
Казалось бы, что может быть проще, чем сделать клик на кнопку. Используй стандартный
View.OnClickListener и будь уверен, что кнопка нажмётся. Однако, не всё может быть столь очевидно.Опытные разработчики сталкивались с какими-то задвоенными действиями в приложении. Например, два запроса в сеть вместо одного. Часто причиной подобного поведения является именно стандартный ClickListener.
Решения может быть два:
• блокировка кнопки до появления какой-то реакции или ответа;
• добавление небольшой задержки при нажатии на кнопку.
Любопытно, что аннотация
@OnClick из библиотеки ButterKnife, использовала именно DebouncingOnClickListener под капотом. Но сегодня, когда основная масса разработчиков использует Kotlin synthetics или View Binding, мы забываем про этот «хак».
Автор в статье напоминает об этой фиче и рассказывает, как просто использовать его, совмещая с extension-функциями Kotlin. Получилось довольно удобно, и теперь можно делать:
my_button.setOnCLick(intervalMillis = 500) {
// Do stuff
}
вместо стандартного клика.
Кто считает, что клик с задержкой — это костыль?
Ask me anything! — Badoo
#статьи
На Хабре есть довольно интересная рубрика, где все желающие могут пообщаться с ребятами из различных команд.
На мой взгляд, это круто, так как не каждый может побывать на конференциях, и встретиться с интересующей командой.
Думаю, что приложение Badoo особо не нуждается в представлении. 🤓
В Android-приложениях этой компании больше 1,3 млн строк кода, а в Android-команде более 20 разработчиков. Основной язык разработки — Kotlin, архитектурные паттерны — MVI и RIBs, база данных — SQLite.
А сегодня разработчики отвечают на вопросы из комментариев.
Задать интересующий вопрос можно тут.
#статьи
На Хабре есть довольно интересная рубрика, где все желающие могут пообщаться с ребятами из различных команд.
На мой взгляд, это круто, так как не каждый может побывать на конференциях, и встретиться с интересующей командой.
Думаю, что приложение Badoo особо не нуждается в представлении. 🤓
В Android-приложениях этой компании больше 1,3 млн строк кода, а в Android-команде более 20 разработчиков. Основной язык разработки — Kotlin, архитектурные паттерны — MVI и RIBs, база данных — SQLite.
А сегодня разработчики отвечают на вопросы из комментариев.
Задать интересующий вопрос можно тут.
Хабр
Ask me anything! Задай вопрос Android-команде Badoo
Предлагаем продолжить добрую традицию Ask me anything на Хабре и поговорить про разработку Android-приложений. Сегодня и завтра Android-команда Badoo будет на связи и ответит на любые вопросы о...
Как именовать цвета в Android?
#статьи #разработка
Нейминг переменных — одна из самых неочевидных вещей при написании нового кода. А правильное именование цветов — это отдельная тема, которой уделяют внимание мало разработчиков.
Уверен, что вы видели подобные цвета в каких-то проектах:
Вторым распространённым подходом является нейминг в стиле палитры Material Colors. Например, тут вы можете увидеть цвета
Интересный подход предлагает автор этой статьи. Он предлагает использовать сервис, который подберет название для абсолютно любого цвета. Тут вы получаете преимущество в отвязке от компонентов приложения и возможность полного переиспользования.
Как по мне, любопытный подход, который можно взять на вооружение.
#статьи #разработка
Нейминг переменных — одна из самых неочевидных вещей при написании нового кода. А правильное именование цветов — это отдельная тема, которой уделяют внимание мало разработчиков.
Уверен, что вы видели подобные цвета в каких-то проектах:
login_button_background или confirmed_bg_gradient_end. Основная проблема — это отсутствие возможности переиспользовать эти цвета без ущерба к смыслу.Вторым распространённым подходом является нейминг в стиле палитры Material Colors. Например, тут вы можете увидеть цвета
red_50, red_100, green_a100 и т.д. Проблема в том, что если вы видите цвета с цифрами на конце, то это не дает полное представление о том, как выглядит этот цвет. Например, красный с индексом 50 — это цвет, который больше похож на розовый. Это делает их повторное использование также затруднительным. Интересный подход предлагает автор этой статьи. Он предлагает использовать сервис, который подберет название для абсолютно любого цвета. Тут вы получаете преимущество в отвязке от компонентов приложения и возможность полного переиспользования.
Как по мне, любопытный подход, который можно взять на вооружение.
Как обеспечить безопасность приложения?
#разработка #статьи #комментарии
Для большинства приложений — безопасность очень важная вещь. Это особенно она важна, если вы работаете с данными пользователей или у вас есть покупки. Ведь никто не хочет, чтобы платной версией приложения пользовались бесплатно. 😉
Автор в статье дал несколько советов, которые значительно улучшат безопасность внутри приложения.
• обфускаций кода — наверное, первая и самая важная вещь, которая должна быть у вас включена. Для этого нужно прописать
• проверка на root — по сути root позволяет пользователям делать на их устройстве чуть больше, чем обычным пользователям, например изменение системных файлов или доступ ко внутреннему хранилищу приложения. Запрет использования приложения на root-устройствах может быть критичным.
Мне не приходилось делать проверку на root, но судя по всему, есть решение в виде библиотеки RootBeer.
• зашифрованное соединение с сервером — не мне рассказывать, что большинство приложений связаны с сервером. Обязательно проверьте, насколько безопасно это соединение: это обязательно должно быть https соединение. Можно добавить ещё Certificate Pinning, которым вы будете шифровать каждый запрос на сервер. Пример есть тут.
• шифрованное локальное хранилище — тут важно оценить «важность» тех данных, которые хранятся на устройстве. Если эти данные позволяют выполнять запросы на сервер от лица пользователя (например, это token), то обязательно стоит задуматься о безопасном хранении этой информации. Для шифрования sharedpreferences можно использовать security-crypto, который хоть и не находится в релизной стадии, но уже работает довольно сносно.
• debug mode и логи — никогда не кладите в логи какую-то важную информацию. Проверьте, включен ли
А что ещё важно учитывать, чтобы сделать приложение безопасным? Давайте обсудим в комментариях
#разработка #статьи #комментарии
Для большинства приложений — безопасность очень важная вещь. Это особенно она важна, если вы работаете с данными пользователей или у вас есть покупки. Ведь никто не хочет, чтобы платной версией приложения пользовались бесплатно. 😉
Автор в статье дал несколько советов, которые значительно улучшат безопасность внутри приложения.
• обфускаций кода — наверное, первая и самая важная вещь, которая должна быть у вас включена. Для этого нужно прописать
minifyenabled = true в вашем build.gradle приложения. Начиная с Android Studio 3.5 по умолчанию включен R8 вместо pro-guard, что, судя по всему, делает реверс-инжениринг приложения тяжелее. Обязательно проверьте своё приложение после включения этого флага и уделите особое внимание enum-классам.• проверка на root — по сути root позволяет пользователям делать на их устройстве чуть больше, чем обычным пользователям, например изменение системных файлов или доступ ко внутреннему хранилищу приложения. Запрет использования приложения на root-устройствах может быть критичным.
Мне не приходилось делать проверку на root, но судя по всему, есть решение в виде библиотеки RootBeer.
• зашифрованное соединение с сервером — не мне рассказывать, что большинство приложений связаны с сервером. Обязательно проверьте, насколько безопасно это соединение: это обязательно должно быть https соединение. Можно добавить ещё Certificate Pinning, которым вы будете шифровать каждый запрос на сервер. Пример есть тут.
• шифрованное локальное хранилище — тут важно оценить «важность» тех данных, которые хранятся на устройстве. Если эти данные позволяют выполнять запросы на сервер от лица пользователя (например, это token), то обязательно стоит задуматься о безопасном хранении этой информации. Для шифрования sharedpreferences можно использовать security-crypto, который хоть и не находится в релизной стадии, но уже работает довольно сносно.
• debug mode и логи — никогда не кладите в логи какую-то важную информацию. Проверьте, включен ли
deguggable = false в релизном билде.А что ещё важно учитывать, чтобы сделать приложение безопасным? Давайте обсудим в комментариях
👍1