Сегодня в выпуске: Jetpack для Android-разработчиков, WorkManager для всех фоновых задач, Android App Bundle вместо тысячи APK, AndroidX, а также другой треш и угар с Google I/O, включая потрясающий рассказ о том, как Android отрисовывает картинку и оптимизирует код. Ну а для любителей Kotlin — Kotlin в Android, Kotlin в браузере, Kotlin в Kotlin, который внутри Java, и два отличных читшита по этому отличному языку.
 

Google I/O

 

Jetpack

На конференции Google I/O много говорили о Jetpack — своего рода прокачанном наборе инструментов, который сама Google рекомендует использовать для создания быстрых, производительных, эффективных и самых-самых в мире приложений.

В целом инструменты достаточно стандартны, это все те же набившие оскомину AppCompat, новомодный Android KTX (кстати, да, Google намекает, что Java пора на покой), компоненты так называемой архитектуры Android: LiveData, ViewModel, Room и так далее. В списке есть и стандартные API Android, такие, например, как менеджер загрузок, а еще Emoji, куда же без них.

Запутав за десять лет экосистему Android до такой степени, что среднестатистический разработчик уже не может понять, куда ему ткнуться, Google решила все-таки внести ясность.

Компоненты Jetpack
Компоненты Jetpack
 

WorkManager

Среди компонентов Jetpack оказался один новый и довольно занятный. Название ему — WorkManager, а история очень и очень интересная. Издревле в Android было два основных метода выполнить фоновую работу: фоновый поток (AsyncTask, например) и сервисы. Последние пользовались особой популярностью, потому как работали независимо от самого приложения, да еще и с возможностью попросить систему о своем перезапуске.

Когда набежала толпа гоблинов, вирусов и говнокодеров, стало ясно, что так дело не пойдет и нужен более контролируемый системой фоновый механизм. Google придумала JobScheduler, подсистему Android 5, которая позволяла отдать системе задачу на выполнение в такое-то и такое-то время, почти как в iOS. Сервисы тем временем неистово подавлялись (а в Android 8 вообще ушли в нелегал).

Со временем JobScheduler обрастал функциональностью, появился его аналог для более старых ОС (Firebase JobDispatcher), а народ все не унимался: ну неудобно нам, убогим, первые версии JobScheduler не работали, другие постоянно менялись, предлагаемая Google альтернатива зависела от самой инфраструктуры Google; плюс у нас тут RxJava и вообще реактивщина, а вы нам какой-то JobScheduler с его идеями из прошлого века.

Вот Google и решила выкатить свой WorkManager с промайзами и обсерверами. Если говорить в двух словах, то WorkManager — это работающая на костях существующего Android библиотека, которая позволяет тебе делать любые фоновые штуки с реактивщиной в нужное тебе время, нужной последовательности и нужных условиях и вообще не заботиться о том, на какой версии все это будет работать (библиотека выберет нужный механизм сама, в зависимости от версии Android).

WorkManager.getInstance().beginWith(firstWork)
  .then(secondWork)
  .then(thirdWork)
  .enqueue()
 

Android App Bundle

Еще один важнейший анонс, сделанный компанией на Google I/O, — это App Bundle (видео), мечта всех домохозяек, взявших Android Studio в руки. Представь, что у тебя есть приложение, в которое понапихано множество самой разной графики в разных разрешениях, поддержка 150 языков, а еще есть сборки нативных библиотек для четырех архитектур.

Чтобы поддерживать все это дело, тебе приходится писать большой build.gradle, который собирал бы для тебя с десяток различных вариантов APK для разных платформ, разрешений экрана, возможно даже языков. Все это пришлось бы отдельно заливать в Play Store (ну ладно, может быть, ты юзаешь devops). В любом случае возни море, а все ради того, чтобы размер APK для каждого устройства и региона был адекватным.

А теперь представь, что ты просто нажимаешь «Собрать приложение» и вместо множества пакетов Android Studio выдает тебе один большой файл формата AAB. И в нем все: все картинки, шрифты, изображения, сборки библиотек — все, что только можно. Ты заливаешь этот файл в Google Play, и на этом твои проблемы заканчиваются: Google Play сам разберет его на множество мелких APK под разные архитектуры, размеры экрана и регионы.

Более того, в данный момент Google тестирует функцию Dynamic feature modules — с ее помощью можно разбивать базовый APK на части, которые будут докачиваться при необходимости. Ну правда, зачем тебе все приложение, если большей частью его функций ты даже не будешь пользоваться?

Внутренний формат AAB
Внутренний формат AAB
 

AndroidX

Ну и в конце, конечно же, об AndroidX. Команда разработчиков support-библиотек, нужных для реализации новых функций ОС на старых устройствах, уже, кажется, сама запуталась и решила привести в порядок все эти com.android.support:appcompat-v7, support-v4 и прочий ворох невнятных, никак не связанных между собой имен.

Теперь у нас есть единое пространство имен для всех библиотек поддержки: androidx. Все, что относится к API самого Android, теперь в пакете android, внешние гугловские библиотеки поддержки — в androidx. Было:

android.support.**
android.databinding.**
android.arch.**
android.arch.persistence.room.**

Стало:

androidx.@
androidx.databinding.@
androidx.room.@
 

Посмотреть

 

Как Android отрисовывает картинку

Drawn out: how Android renders (Google I/O ’18) — интересное видео с рассказом о системе рендеринга Android. Основная цель — донести до зрителя идею, что малейшие строчки их кода и малейшие изменения интерфейса приводят в движение огромные механизмы и это следует иметь в виду. Простые примеры:

  • простейшее окошко со списком состоит из более чем десятка лейаутов;
  • простая операция смены цвета элемента приводит к его полной инвалидации, то есть пересчету состояния и размеров элемента, а кроме того, изменению информации обо всех предках этого элемента;
  • затем эта информация должна быть синхронизирована с потоком отрисовки, работающим с GPU, плюс ему должны быть отданы битмапы;
  • затем список необходимых для отрисовки операций перестраивается с целью их оптимизации на GPU (на видео есть превосходный пример на тему отрисовки Gmail в разных вариантах);
  • с помощью GL-команд выполняется отрисовка нужного изображения, которое затем возвращается обратно в тред отрисовки;
  • затем в дело вступает SurfaceFlinger, который собирает все части интерфейса Android в единое целое.

И это всего лишь то, что происходит при нажатии на элемент списка. В видео также есть рассказ о происходящем во время промотки этого списка. Рекомендую посмотреть.

Иерархия элементов интерфейса простейшего приложения
Иерархия элементов интерфейса простейшего приложения
 

Оптимизация Android P

What’s new in Android Runtime (Google I/O ’18) — еще одно отличное выступление на Google I/O, посвященное оптимизациям в среде исполнения Android P. Выступление касается трех пунктов:

  • Kotlin;
  • память;
  • облачные профили.

С Kotlin все оказалось довольно просто, докладчики рассказали о вынесении null-проверок в вызывающие функции, оптимизациях циклов и некоторых других вещей.

Две остальные части доклада куда интереснее. Во-первых, CompactDex — специальный компактный формат исполняемого файла Dex (в нем хранится код приложений для Android). В Android P формат CompactDex используется для хранения извлеченного из APK кода приложения, а также для хранения кода приложения в оперативной памяти.

В среднем CompactDex позволил сократить размер хранящегося в памяти устройства кода приложения на 11,6%. Это касается и постоянной памяти, и оперативной, но не касается самих приложений, распространяющихся через маркеты.

Также в Android P был усовершенствован JIT-компилятор, а точнее его часть, ответственная за оптимизацию расположения данных в оперативной памяти, когда наиболее часто используемые и нужные при загрузке приложения методы размещаются ближе к началу оперативной памяти процесса. Напомню, что начиная с седьмой версии Android использует гибридный JIT/AOT-компилятор, который сначала выполняет приложения, используя виртуальную машину, а лишь затем переводит приложение в машинные инструкции.

Как происходит обработка установленного APK в Android O и Android P

Как происходит обработка установленного APK в Android O и Android P

Как происходит обработка установленного APK в Android O и Android P

Ну и наконец, облачные профили. Это более простая, но эффективная идея. Во время исполнения любого приложения Android строит профиль его исполнения. В будущем такой профиль позволяет среде исполнения «подстроиться» под приложение и запустить его быстрее.

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

На собственных приложениях Google система облачного профайлинга дала выигрыш в скорости первичного запуска примерно в 20%.

Как работают облачные профили
Как работают облачные профили

В ходе тестирования системы авторы сделали интересные выводы: в среднем в данные профайлинга попали только 14% кода приложения, а это значит, что остальные 86%, скорее всего, вообще не используются. Но это не обязательно мертвый код, это могут быть функции, отключенные на разных версиях Android, или, например, код отладки, отключенный в релизной версии.

 

Очередная экономия батарейки

App Standby Buckets in Android P will help further improve battery life — статья об еще одном интересном новшестве Android P под названием App Standby Buckets.

Предыстория здесь такова: в Android 6 Google придумала новейшую систему массового отстрела приложений, жрущих аккумулятор. Состояла она из двух частей: Doze и App Standby. Во время простоя смартфона (примерно час) в силу вступал Doze, он отключал фоновую активность, запрещал доступ в интернет, снимал вейклоки (они нужны, чтобы удерживать смартфон в режиме бодрствования), откладывал алармы, если они были не особо срочными.

В то же время работала система App Standby. Она занималась практически той же работой, но в отношении отдельно взятых приложений: дескать, раз уж юзер тобой не пользуется, а ты висишь и что-то там качаешь из интернета — лети в бан.

Насколько эффективной была эта система, никто так и не выяснил, но в Android P Google таки умудрилась ее расширить. Теперь речь идет не просто о классификации «работает / не работает», а о целой системе приоритетов. Все приложения теперь разделяются на группы:

  • активные: приложение используется сейчас;
  • регулярные: приложения используются регулярно;
  • частые: приложения используются часто, но не каждый день;
  • редкие: приложения используются реже одного-нескольких дней.

В зависимости от частоты использования Android будет выделять приложениям различные ресурсы. Такая вот дискриминация.

 

Другое

 

Kotlin в браузере

Embedding Kotlin Playground — с виду простой блог-пост, рассказывающий, как встроить среду исполнения Koltin в собственную страницу, где бы она ни хостилась. Сам код находится здесь.

Отмечу также, что у Kotlin есть полноценная веб-среда разработки, с помощью которой можно не только учиться программировать, но и писать полезный код.

 

Скриптовый Kotlin внутри Kotlin, который в Java

Run Kotlin Scripts (kts) from regular Kotlin Programs. Факт номер 1: приложения Kotlin могут быть выполнены в режиме скриптинга (переименовываем файл в .kts и скармливаем его kotlinc). Факт номер 2: Java поддерживает интеграцию со скриптовыми языками (JSR-223). Факт номер 3: по умолчанию Kotlin компилируется в JVM (Java) и наследует почти все ее свойства.

Ну а суть статьи в том, как все это заставить работать вместе и сделать на Kotlin приложение, функциональность которого можно расширять с помощью скриптов на Kotlin. Выглядеть вызов скриптов Kotlin из Kotlin может так:

with(ScriptEngineManager().getEngineByExtension("kts")) {
    eval("val x = 3")
    val res2 = eval("x + 2")
    assertEquals(5, res2)
}

Код доступен в репозитории KtsRunner.

 

Kotlin Cheat Sheet

Kotlin Cheat Sheet — простой понятный читшит о языке Kotlin, который можно повесить на стенку и начинать каждый день с созерцания красивых строк кода. Затрагивает: базовый синтаксис, управляющие структуры (включая фирменные «извращения» Kotlin), типы данных и конвертации, лямбды, разные типы функций, функции-расширения, идиоматические выражения. В целом почти полный курс по языку на семи страницах.

Kotlin Cheat Sheet — и еще один Kotlin Cheat Sheet, более сжатый, сконцентрированный на примерах и быстрых решениях.

 

Развлекуха с Anko

Anko Commons Tutorial — у разработчиков Kotlin есть один мало используемый, очень недооцененный проект. Он носит имя Anko и включает в себя множество подсобных утилит и функций, а в том числе превосходный DSL (язык в языке), позволяющий с комфортом описывать интерфейс без XML и ломания мозга (автор статьи с его помощью написал вполне успешное приложение).

Эта часть статьи посвящена только части Anko Commons, своего рода сборнику быстрых инструментов для Android-разработчиков. Ну и сразу несколько примеров.

Как запустить активность со сложным интентом? Так?

val intent = Intent(this, AnimeDetailActivity::class.java)

intent.putExtra("TITLE_KEY", anime.name)
intent.putExtra("DESCRIPTION_KEY", anime.description)
intent.putExtra("IMDB_LINK_KEY", anime.imdbLink)
intent.putExtra("IMAGE_KEY", anime.imageDrawable)

startActivity(intent)

Слишком увесисто, нам нужен Anko:

private fun openDetailActivity(anime: Anime) {
  startActivity<AnimeDetailActivity>(
      "TITLE_KEY" to anime.name,
      "DESCRIPTION_KEY" to anime.description,
      "IMDB_LINK_KEY" to anime.imdbLink,
      "IMAGE_KEY" to anime.imageDrawable
    )
}

Да какое там, если весь интент состоит из имени класса, то можно вообще сделать так:

startActivity<AboutActivity>()

А как насчет позвонить?

makeCall(002)

Отправить СМС:

sendSMS(номер, текст)

Ну и наши любимые сообщения:

toast("Я сообщение")

Диалоговое окно?

alert("message", "title").show()

Конечно же, его можно расширить, добавить кнопок и прочее.

То же самое с селекторами, прогресс-барами и много чем еще. Вообще, статья отлично иллюстрирует, как ужать код среднестатистического приложения раза этак в три.

 

Библиотеки

  • androidexample365.com — огромное количество примеров реализации тех или иных функций в Android;
  • restring — простая в использовании библиотека, позволяющая хранить строки приложения на удаленном сервере и автоматически загружать их в приложение;
  • palumu — библиотека, позволяющая сделать элементы интерфейса плавающими;
  • PersistantRecyclerAdapter — RecyclerView Adapter, способный сохранять данные между пересозданиями фрагментов и активностей;
  • Cicerone — очередная попытка создать роутер, способный упростить логическую навигацию между компонентами приложения (основана не на фреймворках);
  • Flashbar — очень развитая библиотека для вывода на экран самых разных типов сообщений, начиная от банальных Toast и Snackbar и заканчивая всевозможными окошками со всех сторон экрана;
  • TlsLibrary — Kotlin DSL (язык в языке) для описания TLS-подключений;
  • nanoscope — утилита трассировки с очень низким оверхедом (~20 наносекунд на один метод на Nexus 6);
  • icondialoglib — диалог, позволяющий выбрать иконки, их цвет и другие параметры;
  • domic — реактивная система работы с DOM Android;
  • android-ruler-picker — рулетка для выбора нужных значений;
  • UCE-Handler — библиотека, перехватывающая управление в момент падения приложения и выводящая информационное окно с возможностью просмотреть или отправить лог ошибки.
До и после UCE
До и после UCE
 

Инструменты

  • dereflector — скрипт Frida для дерефлексии Java-кода (превращения непрямых вызовов методов в прямые);
  • Fantastic Malware and Where to Find Them — большой каталог списков всевозможной малвари (в закладки!).

1 комментарий

  1. Аватар

    heavis

    30.05.2018 в 11:12

    Но ведь…код «активности со сложным интентом» не изменился в длине 🙂

Оставить мнение