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. Так почему бы и вам не осчастливить пользователей своим приложением?

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

  • AppGallery Connect. Getting started with Android.

  • Huawei Codelabs

Источник: https://habr.com/ru/post/662297/


Интересные статьи

Интересные статьи

На GitHub размещены миллионы Open Source проектов, но для начинающих разработчиков бывает достаточно сложно поначалу разобраться в принципах их работы, а также в интерфейсе сайта. Это краткое руководс...
В наше время трудно обойтись без компьютера – это факт, так как данный аппарат является основным источником информации, развлечений, а для некоторых и дохода. На данный момент выгоднее вс...
Китайская компания Huawei вплотную занялась избавлением от проблем со стороны США, то есть обходом санкций, наложенных правительством. Полным ходом идет разработка новых процессоров, со...
Во время презентаций летом 2019 года Huawei анонсировала технологию Ark Compiler. По заверениям представителей компании, этот проект с открытым исходным кодом позволяет существенно повысить пла...
Привет, Хабр! Представляю вашему вниманию перевод статьи «Is Java The Best Programming language to Learn First?» автора Javin Paul. Часто получаю вопросы, вроде: «Какой язык программирован...