Huawei Mobile Services и AppGallery: подробная инструкция для начинающих

от автора

Huawei Services, зачем, почему и как собирать проект?

Немного вводных

Huawei поставляет Android-смартфоны без сервисов Google и привычного магазина приложений Google Play, создав аналоги: Huawei Services и AppGallery.

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

Настройка проекта

Уверен, что вы сможете адаптировать инструкцию под вашу версию Gradle,
архитектуру проекта, Kotlin DSL.

Для настройки проекта требуется конфигурационный файл agconnect-services.json аналог google-services.json. Получаем его в консоли разработчика после регистрации проекта.

build.gradle (project)

buildscript {       repositories {           google()           maven { url 'https://developer.huawei.com/repo/' }       }        dependencies {       ....         classpath 'com.huawei.agconnect:agcp:1.4.2.301'      }   }  allprojects {       repositories {           google()            maven { url 'https://developer.huawei.com/repo/' }       }   }

build.gradle (app)

if(getGradle().getStartParameter().getTaskNames().toString().toLowerCase().contains("huawei")) {     apply plugin: 'com.huawei.agconnect' } else {     //Плагины других сервисов }  dependencies { ... implementation "com.huawei.agconnect:agconnect-core:1.4.1.300” ... }

Для ProGuard:

-ignorewarnings  -keep class com.huawei.agconnect.**{*;}

 Для DexGuard:

-ignorewarnings -keep class com.huawei.agconnect.** {*;}  -keep resourcexmlelements **  -keep resources */*

Если есть потребность поддерживать несколько площадок(AppGallery, Google Play)
и сервисов(Huawei, Google), то надо учитывать достаточно частую смену политик маркетов.

Google в одном из обновлений запретила размещать приложения c зависимостями от Huawei Services. Лучшим решением будет разделение сборок.

Отдельные сборки Huawei и Google

Есть несколько реализаций и самый простой выглядит так.

  1. Подготовить build flavours huawei и google

    flavorDimensions "mobileServices" productFlavors {            google {         dimension "mobileServices"     }      huawei {         dimension "mobileServices"         applicationIdSuffix ".huawei"     } }
  2. Разделить все зависимости в build.gradle (app) с помощью googleImplementation
    и huaweiImplementation

     dependencies { ...     huaweiImplementation "com.huawei.agconnect:agconnect-core:1.4.1.300” ... }
  3. Положить agconnect-services.json в директорию src/huawei ,
    а google-services.json в директорию src/google. Так как они нужны только для определённой сборки и application package у них разные. Для публикации huawei сборки к пакету обязательно добавляется “.huawei”

  4. В директории src/main создаём интерфейс будущего сервиса, а реализацию кладём в директории src/huawei и src/google. Названия будут те, которые указаны в productFlavors. При выборе варианта сборки запустится синхронизация Gradle файлов и подставится нужная реализация.

Рассмотрим пример с MessagingService

Важно учитывать ваш подход к асинхронной/мультипоточной работе. В Google Services есть класс Task для получения callback’ов, но в Huawei Services его нет. Kotlin coroutine подходят на замену своей легковесностью. Тогда бы мы использовали suspend function.Допустим у нас жёсткими ограничениями на библиотеки и нет корутин. Тогда можно вспомнить старый добрый Thread. Прекрасное решение, но дорогое, поэтому у нас будет ThreadPoolExecutor, настроенный под наши нужды.

class MessagingServiceImpl : MessagingService {    private var executor: ввExecutorService = ThreadPoolExecutor(         CORE_THREAD_POOL_SIZE,         MAX_THREAD,         KEEP_ALIVE_THREAD_TIME,         TimeUnit.SECONDS,         LinkedBlockingQueue(CAPACITY_QUEUE),         ThreadUtils().threadFactory(Process.THREAD_PRIORITY_BACKGROUND)    )    private val handler = HandlerCompat.createAsync(Looper.getMainLooper())    override fun getToken(successCallback: (token: String) -> Unit) {     val task = Callable {       val token = instanceId.getToken(appId, tokenScope)       if (token != null && token.isNotEmpty())           handler.post {               successCallback(token)           }      }          executor.submit(task)  }    override fun deleteToken(successCallback: () -> Unit) {      val task = Callable {         instanceId.deleteToken(appId, tokenScope)         handler.post {             successCallback()         }     }      executor.submit(task)   }     companion object {      private const val CORE_THREAD_POOL_SIZE = 0      private const val MAX_THREAD = 1      private const val KEEP_ALIVE_THREAD_TIME = 5L      private const val CAPACITY_QUEUE = 1   } }  class ThreadUtils {    fun threadFactory(     priority: Int   ): ThreadFactory = PriorityThreadFactory(priority) }  private class PriorityThreadFactory(     private val threadPriority: Int ) : ThreadFactory {    override fun newThread(runnable: Runnable): Thread {     val wrapperRunnable = Runnable {         try {             Process.setThreadPriority(threadPriority)         } catch (throwable: Throwable) {             Timber.e(throwable)         }         runnable.run()     }          return Thread(wrapperRunnable)   }  }

Вуаля, мы рассмотрели замену Task’ам и подготовили проект для подключения нужных нам сервисов, которое используют идентичное Google Services api.

Tooling

Если у вас есть большой проект с сервисами Google, то плагин ide HMS Toolkit будет очень полезный.

Основные функции:

  • Анализ всех мест использования Google сервисов

  • Замена Google сервисов на Huawei

Предупреждение 1

Плагин зависит от версии Androi Studio. На последних версиях плагин в сторе плагинов внутри студии не найдёшь. Для работы отдельно можно скачать студию более низкой версии.

Предупреждение 2

Если вам пришлось скачать Android Studio более низкой версии
(Смотри предупреждение 1), после установки и открытия проекта можно получить ошибку несовместимости Gradle.

После анализа есть два варианта действий:

  1. Add HMS API. На основе существующих в проекте GMS APIs генерируется XMS adapter (как дополнительный модуль в проекте). Он представляет собой прослойку между нашим кодом и непосредственно вызовом сервисов. Это такие Extension-классы, в которых лежит код, поддерживающий HMS и GMS сервисы одновременно. Add HMS API(в скобках описывается приоритет). В runtime определяется поддерживаемый девайсом вид сервисов и вызываются соответствующие методы. Наш вариант

  • To HMS API – полностью заменяются GMS APIs на HMS APIs.

При желании результаты анализа можно экспортировать, например, в pdf.

Debugging

Всё готово и мы ничего не пропустили. Теперь нам нужно протестировать работоспособность сервисов, но у нас может не быть нужного устройства. Тогда на помощь приходит облачная платформа DigiX Lab для дебага и тестов.

Как можно догадаться, Cloud Debugging предоставляет бесплатное решение для облачной отладки, позволяющее решать такие проблемы:

  • Недостаточное количество моделей устройств

  • Сложности в управлении устройствами

  • Невозможность воспроизвести ошибки

  • Затраты на покупку и управление устройствами

Цель Cloud Testing — это тестирование совместимости, стабильности, производительности и энергопотребления ваших приложений на мобильных устройствах Huawei, а также создание отчётов.

Непрерывная доставка

Для автоматизации сборки можно воспользоваться Publishing API 

Заключение

С этими вводными уже можно экспериментировать, делать первые сборки, используя привычное api. Многие компании, IT гиганты уже поддерживают Huawei Services и разместили свои приложения в AppGallery. Так почему бы и вам не осчастливить пользователей своим приложением?

Полезные ссылки


ссылка на оригинал статьи https://habr.com/ru/post/662297/


Комментарии

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

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