Liaison d’une bibliothèque Java

La communauté Android possède de nombreuses bibliothèques Java que vous pouvez utiliser dans votre application ; ce guide explique comment incorporer des bibliothèques Java dans votre application Xamarin.Android en créant une bibliothèque de liaisons.

Vue d’ensemble

L’écosystème de bibliothèques tierces pour Android est massif. Pour cette raison, il est souvent judicieux d’utiliser une bibliothèque Android existante plutôt que d’en créer une nouvelle. Xamarin.Android offre deux façons d’utiliser ces bibliothèques :

  • Créez une bibliothèque de liaisons qui encapsule automatiquement la bibliothèque avec des wrappers C# afin que vous puissiez appeler du code Java via des appels C#.

  • Utilisez l’interface java native (JNI) pour appeler directement des appels dans le code de la bibliothèque Java. JNI est une infrastructure de programmation qui permet au code Java d’appeler et d’être appelé par des bibliothèques ou des applications natives.

Ce guide explique la première option : comment créer une bibliothèque de liaisons qui encapsule une ou plusieurs bibliothèques Java existantes dans un assembly auquel vous pouvez créer un lien dans votre application. Pour plus d’informations sur l’utilisation de JNI, consultez Utilisation de JNI.

Xamarin.Android implémente des liaisons à l’aide de wrappers mcw (Managed Callable Wrappers). MCW est un pont JNI utilisé lorsque le code managé doit appeler du code Java. Les wrappers callables managés prennent également en charge la sous-classification des types Java et la substitution de méthodes virtuelles sur des types Java. De même, chaque fois que le code d’exécution Android (ART) souhaite appeler du code managé, il le fait via un autre pont JNI appelé Wrappers (ACW). Cette architecture est illustrée dans le diagramme suivant :

Architecture du pont Android JNI

Une bibliothèque de liaisons est un assembly contenant des wrappers callables managés pour les types Java. Par exemple, voici un type Java, MyClass, que nous voulons encapsuler dans une bibliothèque de liaisons :

package com.xamarin.mycode;

public class MyClass
{
    public String myMethod (int i) { ... }
}

Une fois que nous avons généré une bibliothèque de liaisons pour le fichier .jar qui contient MyClass, nous pouvons l’instancier et appeler des méthodes sur celle-ci à partir de C# :

var instance = new MyClass ();

string result = instance.MyMethod (42);

Pour créer cette bibliothèque de liaisons, vous utilisez le modèle bibliothèque de liaisons Java Xamarin.Android. Le projet de liaison résultant crée un assembly .NET avec les classes MCW, le ou les fichiers .jar et les ressources pour les projets de bibliothèque Android incorporés dans celui-ci. Vous pouvez également créer des bibliothèques de liaisons pour Android Archive (. Fichiers AAR) et projets de bibliothèque Android Eclipse. En référençant l’assembly DLL de bibliothèque de liaisons résultant, vous pouvez réutiliser une bibliothèque Java existante dans votre projet Xamarin.Android.

Lorsque vous référencez des types dans votre bibliothèque de liaison, vous devez utiliser l’espace de noms de votre bibliothèque de liaison. En règle générale, vous ajoutez une using directive en haut de vos fichiers sources C#, qui est la version de l’espace de noms .NET du nom du package Java. Par exemple, si le nom du package Java pour votre fichier .jar lié est le suivant :

com.company.package

Ensuite, vous placez l’instruction suivante using en haut de vos fichiers sources C# pour accéder aux types dans le fichier .jar lié :

using Com.Company.Package;

Lors de la liaison d’une bibliothèque Android existante, il est nécessaire de garder à l’esprit les points suivants :

  • Existe-t-il des dépendances externes pour la bibliothèque ? – Toutes les dépendances Java requises par la bibliothèque Android doivent être incluses dans le projet Xamarin.Android sous la forme d’un ReferenceJar ou d’un EmbeddedReferenceJar. Tous les assemblys natifs doivent être ajoutés au projet de liaison en tant que EmbeddedNativeLibrary.

  • Quelle version de l’API Android cible la bibliothèque Android ? – Il n’est pas possible de « rétrograder » le niveau de l’API Android ; Vérifiez que le projet de liaison Xamarin.Android cible le même niveau d’API (ou supérieur) que la bibliothèque Android.

  • Quelle version du JDK a été utilisée pour compiler la bibliothèque ? – Des erreurs de liaison peuvent se produire si la bibliothèque Android a été créée avec une autre version de JDK que celle utilisée par Xamarin.Android. Si possible, recompilez la bibliothèque Android à l’aide de la même version du JDK que celle utilisée par votre installation de Xamarin.Android.

Actions de génération

Lorsque vous créez une bibliothèque de liaisons, vous définissez des actions de build sur .jar ou . Fichiers AAR que vous incorporez dans votre projet de bibliothèque de liaisons : chaque action de génération détermine la façon dont .jar ou . Le fichier AAR sera incorporé (ou référencé par) votre bibliothèque de liaisons. La liste suivante récapitule ces actions de build :

  • EmbeddedJar : incorpore le fichier .jar dans la DLL de bibliothèque de liaisons résultante en tant que ressource incorporée. Il s’agit de l’action de génération la plus simple et la plus couramment utilisée. Utilisez cette option lorsque vous souhaitez que le fichier .jar soit automatiquement compilé en code d’octet et empaqueté dans la bibliothèque de liaisons.

  • InputJar : n’incorpore pas le fichier .jar dans la bibliothèque de liaisons obtenue .DLL. Votre bibliothèque de liaisons .DLL aura une dépendance sur ce fichier .jar au moment de l’exécution. Utilisez cette option lorsque vous ne souhaitez pas inclure le fichier .jar dans votre bibliothèque de liaisons (par exemple, pour des raisons de licence). Si vous utilisez cette option, vous devez vous assurer que l’entrée .jar est disponible sur l’appareil qui exécute votre application.

  • LibraryProjectZip – Incorpore un . Fichier AAR dans la bibliothèque de liaisons obtenue .DLL. Ceci est similaire à EmbeddedJar, sauf que vous pouvez accéder aux ressources (ainsi qu’au code) dans le lié . Fichier AAR. Utilisez cette option lorsque vous souhaitez incorporer un . AAR dans votre bibliothèque de liaisons.

  • ReferenceJar – Spécifie une référence .jar : une référence .jar est un .jar que l’un de vos . jar ou . Les fichiers AAR dépendent de . Cette référence .jar est utilisée uniquement pour satisfaire les dépendances au moment de la compilation. Lorsque vous utilisez cette action de génération, les liaisons C# ne sont pas créées pour la référence .jar et elle n’est pas incorporée dans la bibliothèque de liaisons résultante .DLL. Utilisez cette option lorsque vous créez une bibliothèque de liaisons pour la référence .jar , mais que vous ne l’avez pas encore fait. Cette action de génération est utile pour empaqueter plusieurs .jars(et/ou ). AARs) dans plusieurs bibliothèques de liaisons interdépendantes.

  • EmbeddedReferenceJar : incorpore un fichier .jar de référence dans la bibliothèque de liaisons obtenue .DLL. Utilisez cette action de génération lorsque vous souhaitez créer des liaisons C# pour l’entrée .jar (ou . AAR) et toutes ses références .jar(s) dans votre bibliothèque de liaisons.

  • EmbeddedNativeLibrary : incorpore un .so natif dans la liaison. Cette action de génération est utilisée pour les fichiers .so requis par le fichier .jar lié. Il peut être nécessaire de charger manuellement la bibliothèque .so avant d’exécuter le code à partir de la bibliothèque Java. Ceci est décrit ci-dessous.

Ces actions de génération sont expliquées plus en détail dans les guides suivants.

En outre, les actions de build suivantes permettent d’importer la documentation de l’API Java et de les convertir en documentation XML C# :

  • JavaDocJar est utilisé pour pointer vers le fichier Jar d’archive Javadoc pour une bibliothèque Java conforme à un style de package Maven (généralement FOOBAR-javadoc**.jar**).
  • JavaDocIndex est utilisé pour pointer vers index.html le fichier dans la documentation de référence de l’API HTML.
  • JavaSourceJar est utilisé pour compléter JavaDocJar, pour générer d’abord JavaDoc à partir de sources, puis traiter les résultats comme JavaDocIndex, pour une bibliothèque Java conforme à un style de package Maven (généralement FOOBAR-sources**.jar**).

La documentation de l’API doit être le document par défaut du Kit de développement logiciel (SDK) Java8, Java7 ou Java6 (leur format est différent) ou le style DroidDoc.

Inclusion d’une bibliothèque native dans une liaison

Il peut être nécessaire d’inclure une bibliothèque .so dans un projet de liaison Xamarin.Android dans le cadre de la liaison d’une bibliothèque Java. Lorsque le code Java encapsulé s’exécute, Xamarin.Android ne parvient pas à effectuer l’appel JNI et le message d’erreur java.lang.UnsatisfiedLinkError : méthode native introuvable : s’affiche dans la déconnexion de l’application.

Le correctif consiste à charger manuellement la bibliothèque .so avec un appel à Java.Lang.JavaSystem.LoadLibrary. Par exemple, en supposant qu’un projet Xamarin.Android a une bibliothèque partagée libpocketsphinx_jni.so inclus dans le projet de liaison avec une action de génération d’EmbeddedNativeLibrary, l’extrait de code suivant (exécuté avant d’utiliser la bibliothèque partagée) charge la bibliothèque .so :

Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");

Adaptation des API Java à C⧣

Le générateur de liaison Xamarin.Android modifie certains idiomes et modèles Java pour qu’ils correspondent aux modèles .NET. La liste suivante décrit comment Java est mappé à C#/.NET :

  • Les méthodes Setter/Getter dans Java sont des propriétés dans .NET.

  • Les champs dans Java sont Des propriétés dans .NET.

  • Les interfaces écouteurs/écouteurs dans Java sont des événements dans .NET. Les paramètres des méthodes dans les interfaces de rappel seront représentés par une EventArgs sous-classe.

  • Une classe statique imbriquée dans Java est une classe imbriquée dans .NET.

  • Une classe Inner dans Java est une classe imbriquée avec un constructeur instance en C#.

Scénarios de liaison

Les guides de scénario de liaison suivants peuvent vous aider à lier une bibliothèque (ou des bibliothèques) Java pour l’incorporation dans votre application :

  • Liaison d’un . JAR est une procédure pas à pas pour créer des bibliothèques de liaisons pour les fichiers .jar .

  • Liaison d’un . AAR est une procédure pas à pas pour créer des bibliothèques de liaisons pour . Fichiers AAR. Lisez cette procédure pas à pas pour découvrir comment lier des bibliothèques Android Studio.

  • La liaison d’un projet de bibliothèque Eclipse est une procédure pas à pas pour créer des bibliothèques de liaison à partir de projets de bibliothèque Android. Lisez cette procédure pas à pas pour découvrir comment lier des projets de bibliothèque Android Eclipse.

  • La personnalisation des liaisons explique comment apporter des modifications manuelles à la liaison pour résoudre les erreurs de génération et mettre en forme l’API résultante afin qu’elle soit plus « C#-like ».

  • La résolution des problèmes liés aux liaisons répertorie les scénarios d’erreur de liaison courants, explique les causes possibles et propose des suggestions pour résoudre ces erreurs.