Google стремится продвигать расовую справедливость для черных сообществ. Смотри как.
Эта страница была переведа с помощью Cloud Translation API.
Switch to English

HIDL Java

Android 8.0 реструктурировал ОС Android, чтобы определить четкие интерфейсы между независимой от устройства платформой Android и кодом, специфичным для устройства и поставщика. Android уже определил многие такие интерфейсы в форме интерфейсов HAL, определенных как заголовки C в hardware/libhardware . HIDL заменил эти интерфейсы HAL стабильными версионными интерфейсами, которые могут быть в Java (описана ниже) или как интерфейсы HIDL на стороне клиента и сервера в C ++ .

HIDL-интерфейсы предназначены для использования в основном из собственного кода, и в результате HIDL ориентирован на автоматическую генерацию эффективного кода в C ++. Однако интерфейсы HIDL также должны быть в состоянии использоваться напрямую из Java, поскольку некоторые подсистемы Android (например, телефония), скорее всего, будут иметь интерфейсы Java HIDL.

На страницах этого раздела описывается интерфейс Java для интерфейсов HIDL, подробно описывается, как создавать, регистрировать и использовать службы, а также объясняется, как HAL и клиенты HAL, написанные на Java, взаимодействуют с системой HIDL RPC.

Быть клиентом

Это пример клиента для интерфейса IFoo в пакете android.hardware.foo@1.0 который зарегистрирован как имя службы по default и дополнительной службы с именем настраиваемой службы second_impl .

Добавление библиотек

Вам необходимо добавить зависимости в соответствующую библиотеку заглушек HIDL, если вы хотите ее использовать. Обычно это статическая библиотека:

// in Android.bp
static_libs: [ "android.hardware.foo-V1.0-java", ],
// in Android.mk
LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java

Если вы знаете, что уже используете зависимости от этих библиотек, вы также можете использовать общую связь:

// in Android.bp
libs: [ "android.hardware.foo-V1.0-java", ],
// in Android.mk
LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java

Дополнительные замечания по добавлению библиотек в Android 10

Если у вас есть приложение системы / поставщика, ориентированное на Android 10 и выше, вы должны статически включить эти библиотеки. Для старых приложений старое поведение сохраняется. В качестве альтернативы, можно использовать только классы HIDL из пользовательских JAR-файлов, установленных на устройстве со стабильными API-интерфейсами Java, доступными с использованием существующего механизма uses-library для системных приложений. Для экономии места на устройстве это рекомендуемый подход. Для получения дополнительной информации см. Реализация библиотеки Java SDK .

Начиная с 10, «мелкие» версии этих библиотек также доступны. Они включают в себя рассматриваемый класс, но не включают ни одного из зависимых классов. Например, android.hardware.foo-V1.0-java-shallow включает классы в пакете foo, но не включает классы в android.hidl.base-V1.0-java , который содержит базовый класс всех HIDL интерфейсы. Если вы создаете библиотеку, в которой уже есть базовые классы предпочтительного интерфейса, доступные в качестве зависимости, вы можете использовать следующее:

// in Android.bp
static_libs: [ "android.hardware.foo-V1.0-java-shallow", ],
// in Android.mk
LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java-shallow

Библиотеки HIDL base и manager также больше не доступны в загрузочном classpath. Вместо этого они были перемещены в новое пространство имен с jarjar . Модули на пути загрузки классов, использующие HIDL, должны использовать поверхностные варианты этих библиотек, а также добавить jarjar_rules: ":framework-jarjar-rules" в их Android.bp , чтобы избежать дублирования кода и чтобы приложения системы / поставщика использовали скрытые API ,

Изменение вашего исходного кода Java

Существует только одна версия ( @1.0 ) этого сервиса, поэтому этот код извлекает только эту версию. См. Расширения интерфейса, чтобы узнать, как обрабатывать несколько разных версий сервиса.

import android.hardware.foo.V1_0.IFoo;
...
// retry to wait until the service starts up if it is in the manifest
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IFoo anotherServer = IFoo.getService("second_impl", true /* retry */);
server.doSomething(…);

Предоставление услуги

Программный код в Java, возможно, должен обслуживать интерфейсы для получения асинхронных обратных вызовов от HAL.

Для интерфейса IFooCallback в версии 1.0 пакета android.hardware.foo вы можете реализовать свой интерфейс на Java, выполнив следующие шаги:

  1. Определите ваш интерфейс в HIDL.
  2. Откройте /tmp/android/hardware/foo/IFooCallback.java в качестве ссылки.
  3. Создайте новый модуль для вашей реализации Java.
  4. Изучите абстрактный класс android.hardware.foo.V1_0.IFooCallback.Stub , затем напишите новый класс, чтобы расширить его и реализовать абстрактные методы.

Просмотр автоматически сгенерированных файлов

Чтобы просмотреть автоматически сгенерированные файлы, запустите:

hidl-gen -o /tmp -Ljava \
  -randroid.hardware:hardware/interfaces \
  -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0

Эти команды генерируют каталог /tmp/android/hardware/foo/1.0 . Для файла hardware/interfaces/foo/1.0/IFooCallback.hal создается файл /tmp/android/hardware/foo/1.0/IFooCallback.java , который инкапсулирует интерфейс Java, код прокси и заглушки (оба прокси и заглушки соответствуют интерфейсу).

-Lmakefile генерирует правила, которые запускают эту команду во время сборки и позволяют вам включать android.hardware.foo-V1.0-java и ссылаться на соответствующие файлы. Сценарий, который автоматически делает это для проекта, полного интерфейсов, можно найти по адресу hardware/interfaces/update-makefiles.sh . Пути в этом примере являются относительными; Аппаратные средства / интерфейсы могут быть временным каталогом в вашем дереве кода, чтобы вы могли разработать HAL до его публикации.

Запуск службы

HAL предоставляет интерфейс IFoo , который должен выполнять асинхронные обратные вызовы для инфраструктуры через интерфейс IFooCallback . Интерфейс IFooCallback не зарегистрирован по имени в качестве обнаруживаемой службы; Вместо этого IFoo должен содержать метод, такой как setFooCallback(IFooCallback x) .

Чтобы настроить IFooCallback с версии 1.0 пакета android.hardware.foo , добавьте android.hardware.foo-V1.0-java в Android.mk . Код для запуска службы:

import android.hardware.foo.V1_0.IFoo;
import android.hardware.foo.V1_0.IFooCallback.Stub;
....
class FooCallback extends IFooCallback.Stub {
    // implement methods
}
....
// Get the service you will be receiving callbacks from.
// This also starts the threadpool for your callback service.
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
....
// This must be a persistent instance variable, not local,
//   to avoid premature garbage collection.
FooCallback mFooCallback = new FooCallback();
....
// Do this once to create the callback service and tell the "foo-bar" service
server.setFooCallback(mFooCallback);

Расширения интерфейса

Предполагая, что данный сервис реализует интерфейс IFoo на всех устройствах, возможно, что на конкретном устройстве сервис может предоставить дополнительные возможности, реализованные в расширении интерфейса IBetterFoo , следующим образом:

interface IFoo {
   ...
};

interface IBetterFoo extends IFoo {
   ...
};

Вызов кода, осведомленного о расширенном интерфейсе, может использовать Java-метод castFrom() для безопасного приведения базового интерфейса к расширенному интерфейсу:

IFoo baseService = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IBetterFoo extendedService = IBetterFoo.castFrom(baseService);
if (extendedService != null) {
  // The service implements the extended interface.
} else {
  // The service implements only the base interface.
}