SDK/библиотеки очень важны для любой экосистемы, и экосистема Android ничем не отличается. Я занимаюсь созданием и поставкой SDK/библиотек для Android уже более 7 лет. В этой статье я записал некоторые практики, которым я следую и которые могут помочь нам в написании более качественные SDK.
Используйте аннотации Android
Использование аннотаций помогает сократить шаблонный код и помогает разработчикам интегрировать SDK с предупреждениями lint. Это дает возможность выявлять проблемы прямо во время сборки. Например:
- Добавление аннотации NonNull к параметрам API помогает авторам удалить проверки null внутри тела метода (уменьшая шаблонность) и информирует разработчика о том, что null не должен передаваться в API.
- Аннотирование метода аннотацией Nullable позволяет вызывающему объекту узнать, что API потенциально может возвращать значение null и оно должно корректно обрабатываться на месте вызова.
- Мы можем ограничить непреднамеренное использование общедоступных API, доступных только для внутреннего использования, добавив аннотацию APIRestricTo, что особенно полезно для библиотек, написанных на языке программирования Java.
Используйте инструменты и систему сборки
Учитывая, что слияние манифестов включено по умолчанию в системе сборки, автор SDK должен объявить необходимые компоненты в своем собственном манифесте и не зависеть от разработчиков, добавляющих компоненты. Если в определенных случаях требуется уникальность, например, полномочия контент-провайдера или разрешения для конкретного пакета, то можно воспользоваться переменными, доступными через build.gradle файл приложения.
Именование и дизайн API
Разработчики Android знакомы с именами и поведением API платформы Android. Следовательно, сохранение аналогичного именования и поведения поможет им легко понять API вашего пакета. Например, если у вас есть колбек, который может дополнительно использовать клиент, у вас должен быть булевый тип возврата для него. Если клиент использует обратный вызов и не хочет, чтобы какой-либо SDK обрабатывал его дальше, он должен вернуть true, иначе false. Многие обратные вызовы фреймворка, такие как View.OnClickListener, Activity.onKeyDown() и т. д., работают аналогичным образом.
Обработка исключений
Обработка исключений очень важна для SDK (вероятно, даже больше, чем в приложениях), поскольку это может привести к сбоям в 10 или 100 приложениях или, если уж на то пошло, во всех приложениях, использующих библиотеку. Чтобы гарантировать, что обработка исключений не будет упущена, внедрите проверки lint и статический анализ кода как часть процесса сборки и непрерывной интеграции.
Явный режим API
Для разработчиков, пишущих библиотеки на Kotlin, рекомендуется включить режим Explicit API. При включенном режиме явного API компилятор выполняет дополнительные проверки, которые помогают сделать API библиотеки более понятным и согласованным. Чтобы узнать больше об этом, обратитесь к официальной документации.Или прочитайте мой пост, чтобы узнать больше о том, как включить явный режим API для библиотек Android.
Структура пакета
Мы должны разделить API, которые можно использовать для интеграции приложений, и те, которые предназначены только для внутреннего использования.
Хороший способ разделить API, предназначенные для общего и внутреннего использования, — поместить все внутренние классы во внутренний пакет. Например, все открытые классы будут в пакете <group_id>.<feature_name>, а все внутренние классы будут в пакете <group_id>.<feature_name>.internal.* .
Проверка разрешений
Для некоторых функций требуется разрешение пользователя (или среды выполнения), например к доступу о местоположении. В качестве создателей SDK мы должны просто проверять, предоставлено ли требуемое разрешение или нет, и правильно обрабатывать состояния с отказом в разрешении. Поскольку SDK может быть интегрирован в приложение, у которого может не быть прецедента на запрос дополнительного разрешения, важно обрабатывать его корректно.
Создавайте модульные функции
Со временем, по мере развития компании/продукта, мы добавляем в SDK дополнительные функции, которые могут оказаться полезными не для всех приложений, интегрирующих SDK, и могут привести к их раздуванию. Чтобы приложения не были перегружены ненужным кодом, лучше всего публиковать функции в виде отдельных артефактов для интеграции в приложения.
Сохраняйте низкий размер
Для SDK важно сохранить небольшой размер и не добавлять много байтов к размеру самого приложения. Для этого попробуйте использовать API-интерфейсы фреймворка Android вместо внешних библиотек, где это возможно, внешние библиотеки могут привести к увеличению размера SDK. Здесь важно не переборщить и не изобретать велосипед.
Оптимизация использования ресурсов
Оптимизируйте использование системных ресурсов везде, где это возможно. Например, используйте пакетные сетевые запросы, если нет срочной необходимости немедленно синхронизировать данные, выполняйте фоновые задачи или предварительную выборку данных, когда устройство заряжается, уменьшая влияние на заряд батареи, предварительно извлекайте данные при подключении устройства к WiFi или безлимитной сети.
Соблюдайте минимум шагов интеграции
Соблюдение минимального количества шагов важно для сокращения времени настройки. При минимальных шагах меньше шансов, что разработчики допустят ошибку при интеграции.
Если, чтобы удовлетворить различным требованиям, нам нужно предоставить несколько вариантов конфигурации, используйте конфигурацию по умолчанию, которая позволит разработчикам редактировать/обновлять ее в соответствии со своими требованиями. Это обеспечит минимальное количество шагов для большинства разработчиков.
Публикация
Не размещайте свои jar или aar в CDN или на Github или в любом другом месте. Публикуйте свои SDK в популярных репозиториях, таких как Maven Central, чтобы разработчики могли легко интегрировать/обновлять их с минимальными усилиями.
Версии
Следуйте популярным схемам, таким как семантическое управление версиями. Это помогает разработчикам легко понять, есть ли критическое изменение, являются ли изменения обратно совместимыми и т. д., и принять обоснованное решение о том, стоит ли обновляться сейчас или нет.