Size: a a a

Android Live 🤖

2020 June 12
Android Live 🤖
​​Podlodka Android Crew
#конференции

Не успела завершиться Podlodka Team Lead Crew, как организаторы решили сделать онлайн конференцию для Android разработчиков — Podlodka Android Crew.

Уже с 22 июня нас ждут 2 недели интенсива от экспертов по современным практикам Android-разработки, куча общения и обмена опытом. Темы недели — это архитектура и оптимизация работы мобильных приложений, что актуально для всех всегда.

Сейчас билет стоит 3400 рублей, что довольно дешево, учитывая цену на обычные конференции разработчиков. Уже 18 июня цена повысится до 3900.

А у вас вновь есть шанс выиграть билет на эту конференцию и постетить её бесплатно. Всё что нужно сделать — это оставить свой ник в Telegram в этой форме и 18 июня в 15:00 мы также рандомно выберем победителя.

Торопитесь прокачать свои навыки! 🤓Ссылка на детальное описание тут.
источник
2020 June 14
Android Live 🤖
​​Ещё немного про Android 11
#конференции

В мире Android всё быстро меняется. Особенно, когда дело касается мероприятий, связанных с презентацией свежего Android 11. Вроде мы уже знаем, чего нам ожидать от него, но интересно послушать также и комментарии экспертов.

Уже упоминал вам об онлайн-мероприятиях тут. Осталось только актуализировать даты:

1) Просмотр от Android Broadcast, совместно с Android Dev Podcast. Ссылка на трансляцию тут, начало мероприятия завтра 15 июня в 20:00 по МСК.

2) Просмотр от GDG Russia совместно с Google. Ссылка на трансляцию тут, начало мероприятия в среду, 17 июня в 19:00 по МСК. Надежные источники подтвердили, что на этой трансляции будет приглашенный гость — сам Chet Haase! 😎
Кроме того, у каждого присутствующего будет возможность поучаствовать в квизе и выиграть фирменные штуки от организаторов.

Локальным мероприятиям от GDG также быть, обязательно следи за анонсами! 🤓
источник
2020 June 15
Android Live 🤖
​​Удалённое логирование с Timber и Firebase Realtime Database
#статьи #разработка

Думаю, что никому не нужно объяснять, насколько важно логирование при разработке. Встроенный в Android SDK инструмент — Log неплох, но главная проблема в том, что нам нужно каждый раз подставлять тег в первый параметр.

В качестве альтернативы есть библиотека Timber, которая расширяет стандартную библиотеку и теперь нам не нужно подставлять тег в качестве параметра, а что более важно — мы можем сделать разные деревья для настройки логирования в разных конфигурациях приложения.

Но если нам нужно сделать удаленное логирование? Когда у нас есть устройство рядом, то никаких проблем нет. Но если это устройство не рядом, то проверить логи — отдельная задача.

Интересная связка для удалённого тестирования описана тут. Автор описывает то, как создать отдельное дерево для записи логов в Firebase Realtime Database, получая логи удалённо, лежащими в базе данных.

Получилось довольно удобно, на мой взгляд это отлично подходит для тестовых устройств, но не уверен, что годится, если вы хотите что-то логировать в prod.
источник
2020 June 18
Android Live 🤖
Android 11: что нового?
#конференции

Мы уже видели с вами как минимум 2 конференции, связанные с Android 11, где были обзорно рассмотрены большинство нововведений. Сейчас самое время углубиться в то, что нам принесли эти обновления.

И я буду очень рад вашему участию в мероприятии, где буду одним из ведущих.
Оно состоится 20 июня в 12:00 по Москве. Всего будет три эксперта, которые рассмотрят некоторые из фишек, описанных в нововведениях Android 11.
Мероприятие проводят, совместно, GDG Bryansk и GDG Kaluga.

Эксперты:
Федор Цымбал – работает архитектором в MERA 11 лет. Последние 5 лет занимается разработкой Android Board Support Package (BSP) для микроэлектронного производства. За это время Фёдор получил много опыта работы на разных версиях Android.
Расскажет нам об изменениях в Privacy.

Иван Баранов – разработчик под Android с суммарным опытом более 8 лет. Участвовал в написании различных проектов, последние несколько лет пишет защищённый мессенджер.
Расскажет, что появилось нового в Insets и анимациях клавиатуры.

Инесса Бухонова – 7 лет в Android разработке, помогает делать Android академию СПб, выступала на самых первых GDG в далёком 2013.
Будет выступать с темой Bubbles overview

Продолжительность мероприятия — 2 часа и я уверен, что это будет полезно всем нам. Зарегистрироваться нужно тут. Увидимся! 😎
источник
2020 June 19
Android Live 🤖
​​Создание Twitter splash-screen с использованием MotionLayout
#разработка #дизайн #опрос

Уже не в первый раз пишу вам о возможностях и фишках нового MotionLayout. Последний пост был связан с приложением ScrumPoker, его найдёте тут.

Сегодня ещё один крутой пример. Автор решил написать анимированный Twitter-подобный splash-screen и выбрал самый простой способ — это MotionLayout. Получилось хорошо и количество кода также впечатляет: немногим более 50 строк для MotionScene.

Ссылки на первую и вторую часть статьи тут и тут.

А вы используете MotionLayout у себя в прод-проектах?
источник
Android Live 🤖
​​Результаты конкурса Podlodka Android Crew
#конкурс

Итак, наконец пришло время опубликовать результаты конкурса, описанного тут.

В конкурсе приняло участие 55 человек, при помощи генератора случайных чисел был выбран победитель — @YakovlevAleksey, с чем я его и поздравляю 😎.

Мероприятие стартует 22 июня. Уже известно расписание первой недели, связанной с архитектурой приложений.
Ещё есть шанс присоединиться и получить огромный пласт новых знаний. Ссылка с подробностями здесь.

Видео с выбором победителя тут. До новых конкурсов!
источник
2020 June 24
Android Live 🤖
​​Android ViewModel. Как это работает
#статьи #разработка

Наиболее популярным решением от Google для взаимодействия между Presenter-слоем и View-слоем — это ViewModel. Самым главным преимуществом является механизм сохранения состояния при пересоздании Fragment или Activity.

И кажется, что внутри намешана какая-то магия. 😯 Но если копнуть, то внутри вы обнаружите самый обычный код, где её (магии) «почти» нет.

Копнуть и разобраться в деталях поможет эта статья.

Начиная от 2017 года, автор копается во внутренностях механизмов ViewModel и рассматривает то, как менялись подходы со временем. Интересно, что в самом начале пути, у ViewModel под капотом использовался retained fragment. 🤓
источник
2020 June 25
Android Live 🤖
Друзья, я решил ввести на канале новую рубрику — тестовые задачи по Android. Подобные тесты часто бывают для отсеивания кандидатов на интервью, а также на конференциях.

Итак, начнём с простого задания! 🤓
источник
Android Live 🤖
Для создания фичи, вам нужно использовать структуру данных «ключ-значение».
Вы знаете, что ключом всегда будет являться int и хотите оптимизировать использование памяти.
Какую структуру данных выберите?
Анонимная викторина
31%
HashMap
14%
ArrayMap
4%
TreeSet
45%
SparseArray
7%
HashSet
Проголосовало: 1080
источник
2020 June 29
Android Live 🤖
​​Комментарии к квизу
#quiz

Правильных ответов не так много. Поэтому, после каждого квиза будет пост с описанием, почему правильный ответ является правильным.

HashMap — это структура данных, которая основана на хэш-таблицах. Она реализует интерфейс Map, и это подразумевает хранение в ней пар «ключ-значение». Ключи и значения могут быть любыми типами (Object), в том числе и null (что тоже является распространённым вопросом на собеседовании). Для разрешения коллизий используется метод цепочек.
В целом, вы можете использовать эту структуру для хранения данных, где ключом является Integer. Но в задаче было уточнение — эффективное использование памяти.

ArrayMap — это также структура данных, которая позволяет хранить пары «ключ-значение». С некоторой стороны — это более эффективная по памяти замена HashMap: тут вместо одного большого массива значений, используется два массива, где первый хранит хэши ключей в сортированном порядке, а второй — ключи и значения в соответствии с этим порядком. Коллизии решаются тут методом цепочек.
Однако, получение объекта выполняется медленнее: в отличии от HashMap, где поиск выполняется при помощи получения элемента по хэш-функции, в ArrayMap поиск элемента выполняется бинарным поиском.
Но с точки зрения эффективности памяти эта структура лучше, чем HashMap.

SparseArray — очень похожая на ArrayMap структура. Но её главным отличием является то, что ключами в ней являются примитивные типы, которые занимают ещё меньше памяти и не выполняется операции boxing/unboxing.
С точки зрения получения объектов, результат похож на ArrayMap. Но эта структура наиболее эффективна по памяти, когда вашими ключами является тип int.
У неё также есть «братья»: SparseLongArray, SparseIntArray, SparseBooleanArray, где ключами являются соотвествующие примитивы.

HashSet и TreeSet вовсе не созданы для того, чтобы хранить пары «ключ-значение».

В целом, если ваша задача состоит в хранении небольшого количества элементов (<1000) или у вас не много операций поиска элементов, то стоит присмотреться к альтернативам HashMap. Пара классных и коротких видео про эти структуры тут и тут.

Как вам вообще тема с квизами? Продолжаем?
источник
2020 July 01
Android Live 🤖
​​Store от Dropbox
#библиотека

Есть такое мнение, что единственное чем занимаются разработчики мобильных приложений — это выводят на экран то, что приходит с сервера и красят 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 базами данных. А тут можно почитать немного подробнее о её использовании.
источник
Android Live 🤖
У нас следующий #квиз.

Подобное задание часто встречается на собеседованиях.
источник
Android Live 🤖
Что вернёт функция? 👆
Анонимная викторина
3%
0
33%
1
43%
2
6%
Будет crash
14%
Не скомпилируется
Проголосовало: 1206
источник
2020 July 03
Android Live 🤖
​​Комментарии к квизу
#квиз

Знание из последнего квиза таит в себе подводные камни.
Большинство ответило верно: действительно вернётся 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 не влияет на результат выражения.
Ссылка на документацию тут.

Будьте аккуратны, когда пишите подобный код!
источник
2020 July 04
Android Live 🤖
​​Темы или стили?
#разработка #статьи

В 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.

Тема нужна для для более гибкой настройки компонентов вашего экрана: можно ссылаться на атрибуты темы и в зависимости от них приложение будет выглядеть иначе.

Классная статья, рассказывающая об отличиях стиля и темы тут.

Сейчас как раз буду заниматься рефакторингом стилей в своём приложении, обязательно поделяюсь с вами опытом и сложностями, с которыми пришлось столкнуться😎.
источник
2020 July 06
Android Live 🤖
​​Splitties
#библиотека

Думаю, что многие из тех, кто пишет на Kotlin, согласятся, что при помощи него можно значительно уменьшить количество кода, если сравнивать с Java. Безусловно это польза. В одной презентации увидел фразу, которая звучит как «Less code — less bugs», где есть доля истины.

Помочь в уменьшении кода может коллекция библиотек Splitties. По сути, это набор extention-функций, которые уменьшают число boilerplate кода. Основная часть методов сделана под Android, но разработчики уже написали часть из них и под multiplatform. Особенно радует то, что в проект не нужно тянуть всю библиотеку целиком — можно выбрать только те модули, которые нужны.

Список модулей впечатляет: это и работа с Activity, с Alert Dialog, Permissions, Views. А кроме этого, есть собственный View DSL, немного напоминающий декларативный UI.

Но хочу предостеречь: наличие модулей не отменяет того факта, что нам необходимо изучать библиотеку прежде чем тянуть её в проект. Но в любом случае библиотека интересная и её стоит рассмотреть, как минимум с точки зрения нетипичных решений и функций.
источник
2020 July 09
Android Live 🤖
​​Забытое искусство написания конструкторов
#статьи #разработка

В идеальном мире код разработчика становится лучше день ото дня: то, что мы написали 10 лет назад должно быть лучше того, что мы писали 15 лет назад. Уверен, что в большинстве случаев это именно так.

Сейчас у нас с каждым днём становится всё больше и больше инструментов для разработки, больше «best practises» и современных языков программирования.

Но мы живём в не идеальном мире и часто забываем о некоторых практиках, которых стоит придерживаться. Одна из них — это написание конструкторов.

Конструкторы с большим количеством параметров нарушают принцип единой ответственности: ваш класс делает слишком много одновременно. Максимальное рекомендуемое количество параметров, передаваемое в конструктор — 4. Звучит нереально, учитывая, например, конструкторы Presenter. Автор описывает такой пример:

class ProfilePresenter
@Inject
constructor(
   @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 Live 🤖
Расширение возможностей Android Studio

Продуктивность в написании кода — важная часть работы программиста. И её улучшить можно не только за счет библиотек, но и с помощью плагинов IDE.

Уже сегодня можно послушать о том, как писать плагины самостоятельно. На примере, спикер расскажет как написать свой плагин для генерации кода, который сэкономит много времени при работе с ViewModel + Dagger.

Спикер — Павел Стрельченко — Android разработчик в компании hh.ru, занимается поддержкой основных приложений и разрабатывает внутренние инструменты для улучшения работы своей команды.

Подключайтесь к стриму сегодня, в 20:00 по Москве тут.
источник
2020 July 10
Android Live 🤖
А вот и свежий #квиз на внимательность.

Он также больше подходит как тест на собеседование. И честнее решать его без помощи ввода в среду разработки 😉.
источник
Android Live 🤖
Что вернёт функция? 👆
Анонимная викторина
2%
1
3%
2
63%
3
5%
4
27%
null
Проголосовало: 1162
источник