Partilhar via


Vinculação de bibliotecas Java

O ecossistema de bibliotecas de terceiros para Android é enorme. Por isso, muitas vezes faz sentido usar uma biblioteca Android existente em vez de criar uma nova.

O .NET para Android permite fazer isto com uma Bindings Library que automaticamente envolve a biblioteca com wrappers C# para que possas invocar código Java através de chamadas C#.

Isto é implementado usando Managed Callable Wrappers (MCW). MCW é uma ponte JNI que é usada quando o código gerido precisa de invocar código Java. Os invólucros geridos chamáveis também fornecem suporte para subclassificar tipos Java e para sobrescrever métodos virtuais de tipos Java. Da mesma forma, sempre que o código em tempo de execução Android (ART) deseja invocar código gerido, faz-no através de outra ponte JNI conhecida como Android Callable Wrappers (ACW). Esta arquitetura é ilustrada no diagrama seguinte:

Arquitetura da ponte JNI do Android

Uma Biblioteca de Ligações é um assembly que contém Wrappers Chamáveis Geridos para tipos Java. Por exemplo, aqui está um tipo Java, MyClass, que queremos envolver numa Bindings Library:

package com.contoso.mycode;

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

Depois de gerarmos uma Bindings Library para a .jar que contém MyClass, podemos instancia-la e chamar métodos nela a partir de C#:

var instance = new MyClass ();

string result = instance.MyMethod (42);

Para criar esta Biblioteca de Ligações, utiliza-se o modelo Android Java Binding Library do .NET para Android. O projeto de binding resultante cria uma assemblagem .NET com as classes MCW, ficheiros .jar/.aar e recursos para projetos Android Library incorporados nele. Ao referenciar a assembly resultante da Bindings Library, pode reutilizar uma biblioteca Java existente no seu projeto .NET para Android.

Quando referencias tipos na tua Biblioteca de Encadernação, deves usar o namespace da tua biblioteca de encadernação. Normalmente, adiciona-se uma using diretiva no topo dos ficheiros de origem C# que é a versão do namespace .NET do nome do pacote Java. Por exemplo, se o nome do pacote Java para o seu .jar vinculado for o seguinte:

com.contoso.package

Depois, colocaria a seguinte using instrução no topo dos seus ficheiros fonte C# para aceder aos tipos no ficheiro .jar vinculado:

using Com.Contoso.Package;

Ao ligar uma biblioteca Android existente, é necessário ter em mente os seguintes pontos:

  • Existem dependências externas para a biblioteca? – Quaisquer dependências de Java exigidas pela biblioteca Android devem ser incluídas no projeto .NET para Android através de um pacote NuGet ou como uma AndroidLibrary. Quaisquer assemblies nativos devem ser adicionados ao projeto de binding como uma AndroidNativeLibrary.

  • Que versão da API do Android a biblioteca Android visa? – Não é possível fazer "downgrade" do nível da API Android; deve-se garantir que o projeto de ligação .NET para Android tenha como alvo o mesmo nível de API (ou superior) da biblioteca Android.

Adaptar APIs Java para C⧣

O .NET for Android Binding Generator irá alterar alguns idiomas e padrões Java para corresponder aos padrões .NET. A lista seguinte descreve como o Java é mapeado para C#/.NET:

  • Os métodos Setter/Getter em Java são Propriedades em .NET.

  • Campos em Java são Propriedades em .NET.

  • Ouvintes/Interfaces de Ouvinte em Java são Eventos em .NET. Os parâmetros dos métodos nas interfaces de callback serão representados por uma EventArgs subclasse.

  • Uma classe aninhada estática em Java é uma classe aninhada em .NET.

  • Uma classe Inner em Java é uma classe Nested com um construtor de instância em C#.

Incluindo uma biblioteca nativa numa encadernação

Pode ser necessário incluir uma biblioteca .so num projeto de binding .NET para Android como parte da binding de uma biblioteca Java. Quando o código Java encapsulado for executado, o .NET para Android falhará em fazer a chamada JNI e a mensagem de erro java.lang.UnsatisfiedLinkError: Método nativo não encontrado: aparecerá no logcat out da aplicação.

A solução para isto é carregar manualmente a biblioteca .so com uma chamada para Java.Lang.JavaSystem.LoadLibrary. Por exemplo, assumindo que um projeto .NET para Android tem a biblioteca partilhada libpocketsphinx_jni.so incluída no projeto binding com uma ação de compilação do AndroidNativeLibrary, o seguinte snippet (executado antes de usar a biblioteca partilhada) carregará a biblioteca .so :

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

Cenários de associação

Os seguintes guias de cenários de ligação podem ajudá-lo a vincular uma biblioteca Java (ou bibliotecas) para incorporação na sua aplicação: