Хабрахабр

Патчим AndroidX

На Google I/O 2018 была представлена замена существующим support-библиотекам — AndroidX

Разработка support-библиотек велась во внутренних ветках, которые периодически вливались в Android Open Source Project (AOSP). Изначально, support-библиотеки разрабатывались для обратной совместимости новых API-интерфейсов и были тесно связаны с операционной системой. Кроме того, для работы с support библиотеками необходимо было выкачивать весь код платформы, а это более 40ГБ исходного кода. Такой подход ограничивал мерж пулл-реквестов от сообщества небольшими отрезками времени когда код AOSP и внутренний код гугла были синхронизированы. Для моего диска объемом 250 ГБ это достаточно много.

Например, там реализован компонент для упрощения разработки пользовательского интерфейса AppCompat, компонент для работы с базами данных Room, компонент для фоновых задач WorkManager. Текущий функционал support-библиотек гораздо шире изначальной задумки. Цифра в номере support-библиотеки означает минимальный уровень API, который она поддерживает. Многие из этих библиотек изначально имеют обратную совместимость и слабо привязаны к Android API. Однако, начиная с версии 26. Например, support-v7 поддерживает Android API версии 7 и выше. 0 support-библиотеки поддерживают Android API 14 и выше. 0. Все это указывает на то, что support-библиотеки изжили себя и нуждаются в переосмыслении. Отдельную боль доставляет необходимость одновременного обновления всех support-библиотек.

Разработка была перенесена в отдельную ветку, которая на днях стала публичной. Команда разработчиков потратила несколько лет на выделение support-библиотек в отдельный небольшой проект, с которым можно работать используя Android Studio и Gradle. Еще одно важное отличие новых библиотек состоит в возможности независимого обновления. Обновленные библиотеки получили название AndroidX. 0 и AppCompat версии 1. Гугл обещает бинарную совместимость в рамках одной мажорной версии, что позволит использовать в проекте recyclerview версии 1. 9 в одном проекте.

Мне приходилось несколько раз сильно кастомизировать компоненты из support-библиотек, что приводило к необходимости создавать в моем проекте пакет com.android.support… для доступа к package-private классам/методам/полям. На мой взгляд, это правильный и логичный шаг в развитии support-библиотек.

В качестве учебного пособия я выбрал CardView. Сейчас я предлагаю вместе со мной “хакнуть” какую-нибудь библиотеку из семейства AndroidX. Я собираюсь повлиять на поведение CardView не внося изменений в код, использующий его.

1. Нам потребуется: Компьютер под управлением Linux или MacOS (Windows не поддерживается), Android SDK, опционально — Android Studio ( я использовал версию 3. 3)

Как же Windows?

Исходники можно скачать и с использованием git'а, например, так: git clone --single-branch -b androidx-master-dev https://android.googlesource.com/platform/frameworks/support Однако, в данном случае не будут скачаны утилиты и скомпилированные зависимости. Для скачивания исходников рекомендуется использовать утилиту repo, которая недоступна для Windows. Я не проверял насколько это критично для сборки

Для начала, я подготовил небольшой пример с использованием AndroidX.

Основные моменты:

Используем AndroidX

def cardViewVer = '1.0.0-beta01' dependencies { implementation "androidx.cardview:cardview:$cardViewVer"
}

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="32dp" android:layout_marginEnd="32dp" android:layout_marginLeft="32dp" android:layout_marginRight="32dp" android:layout_marginStart="32dp" android:layout_marginTop="32dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> </androidx.cardview.widget.CardView> </FrameLayout>

public class MainActivity extends Activity
}

В итоге получаем следующее приложение:

drawing

Приступим к AndroidX

Сперва, необходимо установить утилиту repo, созданную для упрощения работы с гитом в контексте андроида.

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

mkdir androidX

Устанавливаем утилиту

сd androidX
mkdir bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ./bin/repo
chmod a+x ./bin/repo
PATH={some_path}/androidX/bin/:$PATH

Поясню, что мы сейчас сделали:
В папке androidX создали папку repo, куда скачали файл по ссылке https://storage.googleapis.com/git-repo-downloads/repo, сделали файл исполняемым и добавили папку bin в PATH в рамках текущей сессии терминала.
В моем случае последняя команда выглядела так: PATH=~/Work/projects/androidX/bin/:$PATH

Качаем исходники AndroidX:

Создаем в папку androidX/androidX-source и делаем ее текущей

mkdir androidX-source
cd androidX-source

Скачается примерно 16 мегабайт данных о существующих ветках в репозитории. Инициализируем локальный репозиторий.

repo init -u https://android.googlesource.com/platform/manifest -b androidx-master-dev

В процессе имя и почта пользователя подтянется из глобального конфига гита, в моем случае, это выглядело так:

Your identity is: Andrew <me@example.com>
If you want to change this, please re-run 'repo init' with --config-name Если в конфиге нет этой информации, то имя и почта будут запрошены.
Далее идет проверка форматированного вывода и запрос на его включение.
Testing colorized output (for 'repo diff', 'repo status'): black red green yellow blue magenta cyan white bold dim ul reverse
Enable color display in this user account (y/N)?

На последний вопрос я ответил утвердительно.
В конце получаем сообщение

repo has been initialized in /Users/{user}/Work/projects/androidX/androidX-source

Далее скачиваем непосредственно исходники (примерно 3 гигабайта)

repo sync -j8 -c

Корневая папка gradle-проекта находится по адресу: androidX/androidX-source/frameworks/support/ Скачанные исходники мы можем открыть в Android Studio или любом другом редакторе.

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

RoundRectDrawable в модуле cardview
Добавим безобидную шутку в метод onDraw Открываем класс androidx.cardview.widget.

canvas.drawText(“Hacked!”, 100, 100, paint);

Полный патч

Адрес репозитория: androidX/androidX-source/out/host/gradle/frameworks/support/build/support_repo Для проекте описана gradle-таска createArchive, которая соберет библиотеки androidX и разместит их в локальном мавен-репозитории.

Для его использования необходимо указать путь в корневом билд-файле.

maven { url 'androidX/androidX-source/out/host/gradle/frameworks/support/build/support_repo' }

На момент написания статьи я собрал androidX библиотеку версии 1. Обратите внимание, что собранная версия может быть новее чем в репозитории гугла. 0-rc01. 0. Посмотреть версию собранной библиотеки можно в локальном мавен репозитории: androidX/androidX-source/out/host/gradle/frameworks/support/build/support_repo/androidx/cardview/cardview/maven-metadata.xml

Обновленный пример

Пересоберем наше приложение и увидим следующую картину:

drawing

AndroidX успешно пропатчен!

Что это нам дает:

  • Мы можем фиксить критичные проблемы не ожидая апдейта от гугла. Кстати, команда AndroidX принимает пулл-реквесты.
  • Сильно кастомизировать androidX библиотеку.

Ссылки по теме:
Документация по support-библиотекам
Пост в блоге разработчиков
Инструкция по контрибьюции в AndroidX
Трекер задач по AndroidX
Исходники AndroidX

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть