Associazione di una libreria Java

La community Android include molte librerie Java che è possibile usare nell'app; Questa guida illustra come incorporare librerie Java nell'applicazione Xamarin.Android creando una libreria binding.

Panoramica

L'ecosistema di librerie di terze parti per Android è enorme. Per questo motivo, spesso ha senso usare una libreria Android esistente che crearne una nuova. Xamarin.Android offre due modi per usare queste librerie:

  • Creare una libreria binding che esegue automaticamente il wrapping della libreria con wrapper C# in modo da poter richiamare il codice Java tramite chiamate C#.

  • Usare Java Native Interface (JNI) per richiamare direttamente le chiamate nel codice della libreria Java. JNI è un framework di programmazione che consente al codice Java di chiamare ed essere chiamato da applicazioni o librerie native.

Questa guida illustra la prima opzione: come creare una libreria binding che esegue il wrapping di una o più librerie Java esistenti in un assembly a cui è possibile collegarsi nell'applicazione. Per altre informazioni sull'uso di JNI, vedere Uso di JNI.

Xamarin.Android implementa le associazioni usando i wrapper chiamabili gestiti (MCW). MCW è un bridge JNI usato quando il codice gestito deve richiamare il codice Java. I wrapper chiamabili gestiti forniscono anche il supporto per la sottoclassazione dei tipi Java e per l'override dei metodi virtuali nei tipi Java. Analogamente, ogni volta che il codice di runtime Android (ART) vuole richiamare codice gestito, lo fa tramite un altro bridge JNI noto come Android Callable Wrapper (ACW). Questa architettura è illustrata nel diagramma seguente:

Android JNI bridge architecture

Una libreria binding è un assembly contenente wrapper chiamabili gestiti per i tipi Java. Ad esempio, ecco un tipo Java, MyClass, che si vuole eseguire il wrapping in una libreria binding:

package com.xamarin.mycode;

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

Dopo aver generato una libreria binding per il .jar che contiene MyClass, è possibile crearne un'istanza e chiamare i metodi da C#:

var instance = new MyClass ();

string result = instance.MyMethod (42);

Per creare questa libreria binding, usare il modello libreria di binding Java Xamarin.Android. Il progetto di associazione risultante crea un assembly .NET con le classi MCW, i file .jar e le risorse per i progetti di libreria Android incorporati. È anche possibile creare librerie di binding per l'archivio Android (. File AAR) e progetti di libreria Android Eclipse. Facendo riferimento all'assembly DLL della libreria binding risultante, è possibile riutilizzare una libreria Java esistente nel progetto Xamarin.Android.

Quando si fa riferimento ai tipi nella libreria di binding, è necessario usare lo spazio dei nomi della libreria di binding. In genere, si aggiunge una using direttiva all'inizio dei file di origine C# che rappresenta la versione dello spazio dei nomi .NET del nome del pacchetto Java. Ad esempio, se il nome del pacchetto Java per il .jar associato è il seguente:

com.company.package

Inserire quindi l'istruzione seguente using all'inizio dei file di origine C# per accedere ai tipi nel file .jar associato:

using Com.Company.Package;

Quando si associa una libreria Android esistente, è necessario tenere presenti i punti seguenti:

  • Esistono dipendenze esterne per la libreria? : tutte le dipendenze Java richieste dalla libreria Android devono essere incluse nel progetto Xamarin.Android come ReferenceJar o come EmbeddedReferenceJar. Tutti gli assembly nativi devono essere aggiunti al progetto di associazione come EmbeddedNativeLibrary.

  • Quale versione dell'API Android ha come destinazione la libreria Android? – Non è possibile effettuare il "downgrade" del livello api Android; assicurarsi che il progetto di associazione Xamarin.Android sia destinato allo stesso livello API (o superiore) della libreria Android.

  • Quale versione di JDK è stata usata per compilare la libreria? - Gli errori di associazione possono verificarsi se la libreria Android è stata compilata con una versione diversa di JDK rispetto all'uso di Xamarin.Android. Se possibile, ricompilare la libreria Android usando la stessa versione di JDK usata dall'installazione di Xamarin.Android.

Azioni di compilazione

Quando si crea una libreria binding, si impostano le azioni di compilazione nel .jar o . File AAR incorporati nel progetto libreria binding: ogni azione di compilazione determina il modo in cui il .jar o . Il file AAR verrà incorporato in (o a cui si fa riferimento) nella libreria binding. L'elenco seguente riepiloga queste azioni di compilazione:

  • EmbeddedJar : incorpora il .jar nella DLL della libreria binding risultante come risorsa incorporata. Questa è l'azione di compilazione più semplice e più comunemente usata. Usare questa opzione quando si desidera che la .jar compilata automaticamente in codice byte e inserita nel pacchetto nella libreria binding.

  • InputJar : non incorpora il .jar nella .DLL della libreria binding risultante. La libreria binding .DLL avrà una dipendenza da questo .jar in fase di esecuzione. Usare questa opzione quando non si vuole includere il .jar nella libreria binding, ad esempio per motivi di licenza. Se usi questa opzione, devi assicurarti che il .jar di input sia disponibile nel dispositivo che esegue l'app.

  • LibraryProjectZip : incorpora un oggetto . File AAR nella libreria binding risultante .DLL. È simile a EmbeddedJar, ad eccezione del fatto che è possibile accedere alle risorse (nonché al codice) nell'oggetto associato. File AAR. Usare questa opzione quando si vuole incorporare un oggetto . AAR nella libreria binding.

  • ReferenceJar: specifica un .jar di riferimento: un riferimento .jar è un .jar che uno dei .jar associati o . I file AAR dipendono. Questo riferimento .jar viene usato solo per soddisfare le dipendenze in fase di compilazione. Quando si usa questa azione di compilazione, le associazioni C# non vengono create per il .jar di riferimento e non sono incorporate nella libreria binding risultante .DLL. Usare questa opzione quando si crea una libreria binding per il riferimento .jar ma non è ancora stata eseguita. Questa azione di compilazione è utile per la creazione di pacchetti di più .jar(e/o . AAR) in più librerie di binding interdipendenti.

  • EmbeddedReferenceJar: incorpora un .jar di riferimento nella .DLL della libreria binding risultante. Usare questa azione di compilazione quando si vogliono creare associazioni C# per entrambi i .jar di input (o . AAR) e tutti i relativi .jar di riferimento nella libreria binding.

  • EmbeddedNativeLibrary: incorpora un file .so nativo nell'associazione. Questa azione di compilazione viene usata per i file con estensione so richiesti dal file .jar associato. Potrebbe essere necessario caricare manualmente la libreria .so prima di eseguire il codice dalla libreria Java. Questo è descritto di seguito.

Queste azioni di compilazione sono illustrate in modo più dettagliato nelle guide seguenti.

Inoltre, vengono usate le azioni di compilazione seguenti per importare la documentazione dell'API Java e convertirle nella documentazione XML C#:

  • JavaDocJar viene usato per puntare all'archivio Jar Javadoc per una libreria Java conforme a uno stile di pacchetto Maven (in genere FOOBAR-javadoc**.jar**).
  • JavaDocIndex viene usato per puntare al index.html file all'interno del codice HTML della documentazione di riferimento dell'API.
  • JavaSourceJar viene usato per integrare JavaDocJar, per generare prima JavaDoc da origini e quindi considerare i risultati come JavaDocIndex, per una libreria Java conforme a uno stile di pacchetto Maven (in genere FOOBAR-sources**.jar**).

La documentazione dell'API deve essere il doclet predefinito da Java8, Java7 o Java6 SDK (sono tutti in formato diverso) o dallo stile DroidDoc.

Inclusione di una libreria nativa in un'associazione

Potrebbe essere necessario includere una libreria so in un progetto di associazione Xamarin.Android come parte dell'associazione di una libreria Java. Quando viene eseguito il codice Java sottoposto a wrapping, Xamarin.Android non riuscirà a eseguire la chiamata JNI e il messaggio di errore java.lang.UnsatisfiedLinkError: native method not found: verrà visualizzato nel logcat out per l'applicazione.

La correzione per questa operazione consiste nel caricare manualmente la libreria .so con una chiamata a Java.Lang.JavaSystem.LoadLibrary. Si supponga, ad esempio, che un progetto Xamarin.Android abbia una libreria condivisa libpocketsphinx_jni.so inclusa nel progetto di associazione con un'azione di compilazione EmbeddedNativeLibrary, il frammento di codice seguente (eseguito prima di usare la libreria condivisa) caricherà la libreria .so:

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

Adattamento di API Java a C⧣

Il generatore di binding Xamarin.Android modificherà alcuni idiomi e modelli Java in modo che corrispondano ai modelli .NET. L'elenco seguente descrive il mapping di Java a C#/.NET:

  • I metodi Setter/Getter in Java sono Proprietà in .NET.

  • I campi in Java sono Proprietà in .NET.

  • Le interfacce listener/listener in Java sono eventi in .NET. I parametri dei metodi nelle interfacce di callback saranno rappresentati da una sottoclasse EventArgs .

  • Una classe annidata statica in Java è una classe annidata in .NET.

  • Una classe Inner in Java è una classe Annidata con un costruttore di istanza in C#.

Scenari di associazione

Le guide dello scenario di associazione seguenti consentono di associare una libreria Java (o librerie) per l'incorporazione nell'app:

  • Associazione di un oggetto . JAR è una procedura dettagliata per la creazione di librerie di binding per .jar file.

  • Associazione di un oggetto . AAR è una procedura dettagliata per la creazione di librerie di binding per . File AAR. Leggere questa procedura dettagliata per informazioni su come associare le librerie di Android Studio.

  • L'associazione di un progetto di libreria Eclipse è una procedura dettagliata per la creazione di librerie di binding da progetti di libreria Android. Leggere questa procedura dettagliata per informazioni su come associare progetti di libreria Android Eclipse.

  • La personalizzazione delle associazioni spiega come apportare modifiche manuali all'associazione per risolvere gli errori di compilazione e modellare l'API risultante in modo che sia più simile a "C#".

  • Risoluzione dei problemi relativi alle associazioni elenca gli scenari di errore di associazione comuni, illustra le possibili cause e offre suggerimenti per la risoluzione di questi errori.