[Разработка под Android] Создание SDK под Android в стиле Single-Activity
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Single activity подходом при создании конечного приложения под Android никого не удивишь. Но мы пошли дальше и использовали No-Activity при разработке SDK. Сейчас разберемся для чего это понадобилось, возникшие сложности и как их решали.Стандартные 3rd party SDK в AndroidКак обычно работают внешние SDK в Android? Открывается Activity библиотеки, выполняется некая работа, при необходимости возвращается результат в onActivityResult.
Стандартная схема работы SDK.Обычно такого подхода хватает, когда SDK выполняет целиком инкапсулированную функцию и не зависит от внешнего приложения. Но иногда необходимо обеспечить более тесное взаимодействие между приложением и SDK, например:
Желаемый стек экранов приложения и SDKПолучается, что экраны нашего SDK должны быть частью внешнего приложения. Точно также, как вы можете использовать, например, MapFragment от Google. Итого, при стандартном подходе, мы сталкиваемся с рядом трудностей и ограничений.Проблемы при стандартном подходе к SDK
- Если вам нужно несколько взаимодействий между SDK и приложением, то придется открывать-закрывать Activity от SDK и аккуратно обрабатывать передачу данных туда-обратно.
- Сложно поддержать такой логический порядок экранов, когда элементы приложения чередуются с SDK. (Спойлер: это можно понадобится, но редко).
- При относительно долгом возможном нахождении в SDK внешнее приложение может уйти в Lock Screen. Такое может случиться, если Lock реализован на колбеках жизненного цикла Activity.
No-Activity подход при разработке SDKИтак, мы решили, что основная проблема в том, что контекст (Activity) внешнего приложения и SDK разные. Отсюда следует резонное решение - отказаться от контекста SDK и во внешнее приложение поставлять только фрагменты. В таком случае разработчик сможет сам управлять стеком экранов.
No-Activity SDK на ФрагментахДанный подход имеет как ряд плюсов, так и значительные минусы. Какие же?Плюсы No-Acitivty SDK
- Приложение и SDK имеют общий контекст, т.е. для пользователя это выглядит как абсолютно единое приложение.
- Основное приложение имеет свой стек фрагментов, а SDK - свой через childFragmentManager.
- Можно организовать любой порядок экранов и наложений элементов, т.к. навигация доступна и для внешнего приложения.
Минусы No-Acitivty SDK
- Внешнее приложение должно изначально работать с фрагментами, желательно вообще быть Single-Activity.
- У SDK нет своего контекста, если хотите использовать dagger - придется исхитриться (но это все же возможно).
- SDK может влиять на внешнее Acitivty, т.к. requireActivity вернет именно его. Надо полностью доверять SDK.
- Activity будет получать onActivityResult, и, вероятно, придется его прокидывать во фрагменты.
- Разработчику внешнего приложения сложнее интегрировать SDK, т.к. простой вызов Activity уже не сработает.
Использование 3rd party библиотек внутри SDKПри любом подходе так или иначе придется использовать библиотеки внутри SDK. Это в свою очередь может привести к коллизии версий с внешним приложением. А части библиотек, например dagger2 нужен будет выделенный контекст.Dagger2 внутри SDKДля использования dagger зачастую в приложении используется класс Application. В случае с SDK так сделать не получится, потому что Application, вероятно, будет перетерт со стороны внешнего приложения.Нужен отдельный класс, который заведомо не будет испорчен внешним приложением.
internal object ComponentHolder {
lateinit var appComponent: SdkAppComponent
private set
@Synchronized
fun init(ctx: Context) {
if (this::appComponent.isInitialized) return
appComponent = DaggerSdkAppComponent
.builder()
.sdkAppModule(SdkAppModule(ctx))
.build()
}
}
Остается только лишь понять, откуда вызвать init, да так, чтобы в процессе жизни SDK быть уверенным, что инициализация выполнилась до любой другой работы. Для этого можно использовать одну точку входа в SDK. Назовем ее EntryPointFragment. Данный фрагмент и будет виден внешнему приложению как единственная точка входа в SDK. Вся дальнейшая навигация внутри SDK будет происходить уже в нем через childFragmentManager.Как раз при создании EntryPointFragment можно и инициализировать ComponentHolder для Dagger.
override fun onCreate(savedInstanceState: Bundle?) {
ComponentHolder.init(requireActivity())
ComponentHolder.appComponent.inject(this)
super.onCreate(savedInstanceState)
}
Итого, на выходе мы получили ComponentHolder, который можно использовать внутри SDK для инъекции нужных компонент.Устранение коллизии в версияхС данной проблемой столкнулись при обновлении версии okhttp3 до новой major версии 4.+. В ней добавили улучшенную поддержку Kotlin, в том числе, например, доступ к коду ошибки через code() теперь стало ошибкой. Клиенты SDK, используя либо 3, либо 4 версию должны получать ту же внутри SDK, иначе все сломается.Это реально сделать, вынеся код с коллизиями в отдельный модуль. В нем будут 2 flavor:
flavorDimensions("okhttpVersion")
productFlavors {
v3 {
dimension = "okhttpVersion"
}
v4 {
dimension = "okhttpVersion"
}
}
dependencies {
v3Api okhttp3.core
v3Api okhttp3.logging
v4Api okhttp4.core
v4Api okhttp4.logging
}
В двух разных папках, отвечающих за каждый flavor будут одинаковые классы, один из которых будет использовать code() а другой code.
// Code in v3 folder
class ResponseWrapper(private val response: Response) {
val code : Int
get() = response.code()
}
// Code in v4 folder
class ResponseWrapper(private val response: Response) {
val code : Int
get() = response.code
}
Остается только на уровне приложения выбрать необходимый конфиг и дальше правильная версия приедет в финальный проект.Подсказка: если вы сами используете свой же модуль в проекте и подключаете как исходники, не забудьте следующее:
defaultConfig {
...
missingDimensionStrategy 'okhttpVersion', 'v4'
}
В таком случае вы избавитесь от конфликта при сборке. Иначе просто версия не найдется.ЗаключениеРазработка SDK, если сравнивать с просто Android приложением, намного сложнее, но порой интереснее. Также требования к качеству конечного продукта выше - если что-то упадет, то упадет не у вас, а у вашего клиента, что прямо очень плохо.
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка мобильных приложений, Разработка под Android] Делаем код в адаптере чище с помощью MergeAdapter
- [Разработка мобильных приложений, Разработка под Android] Создание сложного списка элементов за 20 минут в Android на базе Groupie
- [Java, Разработка мобильных приложений, Разработка под Android, Kotlin, Gradle] Встраиваем карты от Huawei в Android приложение
- [Разработка под Android, Тестирование мобильных приложений, Kotlin] Паттерн PageObject в Kotlin для UI-тестирования Android (перевод)
- [Информационная безопасность] Android Guards. История создания, развития и первый meetup
- [JavaScript] Удобная платформа для подбора библиотек и фреймворков JavaScript — openbase (перевод)
- [Gradle, Java, Kotlin, Разработка мобильных приложений, Разработка под Android] Встраиваем геолокацию от Huawei в Android приложение
- [Разработка мобильных приложений, Разработка под Android, Kotlin, Учебный процесс в IT] Android Academy Fundamentals: теперь прямо у тебя дома
- [Программирование, Разработка под Android] Избегайте внедрения внешних библиотек в свой проект
- В ядро платформы Android перенесена поддержка VPN WireGuard
Теги для поиска: #_razrabotka_pod_android (Разработка под Android), #_android, #_sdk, #_biblioteka (библиотека), #_android_development, #_android_sdk, #_android_os, #_biblioteki (библиотеки), #_razrabotka_pod_android (
Разработка под Android
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:37
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Single activity подходом при создании конечного приложения под Android никого не удивишь. Но мы пошли дальше и использовали No-Activity при разработке SDK. Сейчас разберемся для чего это понадобилось, возникшие сложности и как их решали.Стандартные 3rd party SDK в AndroidКак обычно работают внешние SDK в Android? Открывается Activity библиотеки, выполняется некая работа, при необходимости возвращается результат в onActivityResult. Стандартная схема работы SDK.Обычно такого подхода хватает, когда SDK выполняет целиком инкапсулированную функцию и не зависит от внешнего приложения. Но иногда необходимо обеспечить более тесное взаимодействие между приложением и SDK, например: Желаемый стек экранов приложения и SDKПолучается, что экраны нашего SDK должны быть частью внешнего приложения. Точно также, как вы можете использовать, например, MapFragment от Google. Итого, при стандартном подходе, мы сталкиваемся с рядом трудностей и ограничений.Проблемы при стандартном подходе к SDK
No-Activity SDK на ФрагментахДанный подход имеет как ряд плюсов, так и значительные минусы. Какие же?Плюсы No-Acitivty SDK
internal object ComponentHolder {
lateinit var appComponent: SdkAppComponent private set @Synchronized fun init(ctx: Context) { if (this::appComponent.isInitialized) return appComponent = DaggerSdkAppComponent .builder() .sdkAppModule(SdkAppModule(ctx)) .build() } } override fun onCreate(savedInstanceState: Bundle?) {
ComponentHolder.init(requireActivity()) ComponentHolder.appComponent.inject(this) super.onCreate(savedInstanceState) } flavorDimensions("okhttpVersion")
productFlavors { v3 { dimension = "okhttpVersion" } v4 { dimension = "okhttpVersion" } } dependencies { v3Api okhttp3.core v3Api okhttp3.logging v4Api okhttp4.core v4Api okhttp4.logging } // Code in v3 folder
class ResponseWrapper(private val response: Response) { val code : Int get() = response.code() } // Code in v4 folder
class ResponseWrapper(private val response: Response) { val code : Int get() = response.code } defaultConfig {
... missingDimensionStrategy 'okhttpVersion', 'v4' } =========== Источник: habr.com =========== Похожие новости:
Разработка под Android ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:37
Часовой пояс: UTC + 5