Dans Android 8.0, l'architecture du système d'exploitation Android a été repensée afin de définir des interfaces claires.
entre la plate-forme Android indépendante de l'appareil et la plate-forme spécifique à l'appareil et au fournisseur.
du code source. Android a déjà défini de nombreuses interfaces de ce type sous la forme de HAL.
interfaces, définies comme des en-têtes C dans hardware/libhardware
. HIDL
remplacé ces interfaces HAL par des interfaces stables avec gestion des versions, qui peuvent
soit en Java (décrit ci-dessous), soit en mode HIDL côté client et côté serveur.
interfaces en C++.
Les interfaces HIDL sont destinées à être utilisées principalement à partir du code natif et en tant que HIDL résultat est axé sur la génération automatique d’un code efficace en C++. Toutefois, Les interfaces HIDL doivent également être disponibles pour une utilisation directement à partir de Java, car certaines Les sous-systèmes (tels que la téléphonie) ont des interfaces Java HIDL.
Les pages de cette section décrivent l'interface Java pour les interfaces HIDL, détailler comment créer, enregistrer et utiliser les services, et expliquer comment les HAL et HAL les clients écrits en Java interagissent avec le système HIDL RPC.
Exemple de client
Voici un exemple de client pour une interface IFoo
dans un package
android.hardware.foo@1.0
enregistré en tant que nom de service
default
et un service supplémentaire avec le nom de service personnalisé
second_impl
Ajouter des bibliothèques
Vous devez ajouter des dépendances à la bibliothèque bouchon HIDL correspondante si que vous souhaitez l'utiliser. Il s'agit généralement d'une bibliothèque statique:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Si vous savez que vous extrayez déjà des dépendances sur ces bibliothèques, vous peuvent également utiliser le lien partagé:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Éléments supplémentaires à prendre en compte pour ajouter des bibliothèques sous Android 10
Si vous disposez d'une application système ou d'un fournisseur qui cible Android 10 ou une version ultérieure,
vous pouvez inclure ces bibliothèques
de manière statique. Vous pouvez également utiliser des classes HIDL (uniquement)
à partir de fichiers JAR personnalisés installés sur l'appareil, avec des API Java stables mises à disposition
à l'aide du mécanisme uses-library
existant pour les applications système. La
la deuxième méthode permet d'économiser
de l'espace sur l'appareil. Pour en savoir plus, consultez Implémenter la bibliothèque du SDK Java. Pour
applications plus anciennes, l'ancien comportement est conservé.
À partir d'Android 10, version superficielle versions de ces bibliothèques
sont également à disposition. Il s'agit du cours en question, mais pas
des classes dépendantes. Par exemple,
android.hardware.foo-V1.0-java-shallow
inclut des classes dans l'élément "foo"
mais n'inclut pas les classes
android.hidl.base-V1.0-java
, qui contient la classe de base de toutes
Interfaces HIDL Si vous créez une bibliothèque qui dispose déjà
de base de l'interface disponibles en tant que dépendances, vous pouvez utiliser le code suivant:
// 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
Les bibliothèques de base et de gestionnaires HIDL ne sont également plus disponibles au démarrage
classpath pour les applications (auparavant, elles étaient parfois utilisées en tant qu'API cachées en raison de
le Classloader d'abord délégué d'Android). Au lieu de cela, ils ont été déplacés vers un nouveau
avec jarjar
, et les applications qui les utilisent (nécessairement les privilèges
applications) doivent disposer de leurs propres copies. modules sur le classpath de démarrage à l'aide de
HIDL doit utiliser les variantes superficielles de ces bibliothèques Java et ajouter
jarjar_rules: ":framework-jarjar-rules"
à leur
Android.bp
pour utiliser la version de ces bibliothèques existante
dans le classpath de démarrage.
Modifier votre source Java
Il n'existe qu'une seule version (@1.0
) de ce service. Ce code
ne récupère que cette version. Voir
extensions d'interface
sur la façon de gérer plusieurs
versions différentes du service.
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(…);
Fournir un service
Le code du framework en Java peut avoir besoin de diffuser des interfaces pour recevoir des des rappels HAL.
Pour l'interface IFooCallback
de la version 1.0 de
android.hardware.foo
, vous pouvez implémenter votre interface dans
Java, procédez comme suit:
- Définissez votre interface dans HIDL.
- Ouvrir
/tmp/android/hardware/foo/IFooCallback.java
en tant que référence. - Créez un module pour votre implémentation Java.
- Examiner la classe abstraite
android.hardware.foo.V1_0.IFooCallback.Stub
, puis écrire une nouvelle classe pour l'étendre et implémenter les méthodes abstraites.
Afficher les fichiers générés automatiquement
Pour afficher les fichiers générés automatiquement, exécutez la commande suivante:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Ces commandes génèrent le répertoire
/tmp/android/hardware/foo/1.0
Pour le fichier
hardware/interfaces/foo/1.0/IFooCallback.hal
, cela génère
fichier /tmp/android/hardware/foo/1.0/IFooCallback.java
, qui
encapsule l'interface Java, le code proxy et les bouchons (proxy et
bouchons sont conformes à l'interface).
-Lmakefile
génère les règles qui exécutent cette commande lors de la compilation
et vous permettre d'inclure
android.hardware.foo-V1.0-java
et associez-le à la
les fichiers appropriés. Un script qui le fait automatiquement
pour un projet rempli de
interfaces sont accessibles à l'adresse hardware/interfaces/update-makefiles.sh
.
Dans cet exemple, les chemins d'accès sont relatifs ; du matériel/des interfaces peut être
dans votre arborescence de code pour vous permettre de développer une HAL avant
de les publier.
Exécuter un service
Le HAL fournit l'interface IFoo
, qui doit effectuer des appels asynchrones
des rappels au framework sur l'interface IFooCallback
. La
L'interface IFooCallback
n'est pas enregistrée par son nom comme visible
service; Au lieu de cela, IFoo
doit contenir une méthode telle que
setFooCallback(IFooCallback x)
Pour configurer IFooCallback
à partir de la version 1.0 de
Package android.hardware.foo
, ajouter
De android.hardware.foo-V1.0-java
à Android.mk
. Le code
pour exécuter le service:
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 from which you will be receiving callbacks. // 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);
Extensions d'interface
En supposant qu'un service donné implémente l'interface IFoo
sur toutes
il est possible que sur un appareil particulier, le service fournisse
des fonctionnalités supplémentaires implémentées dans l'extension d'interface
IBetterFoo
, comme suit:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Appeler le code de l'interface étendue peut utiliser la méthode
castFrom()
Méthode Java pour caster en toute sécurité l'interface de base vers la
interface étendue:
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. }