No Android 8.0, o SO Android foi reprojetado para definir interfaces claras
entre a plataforma Android independente de dispositivos e configurações
o código-fonte. O Android já definiu muitas dessas interfaces na forma de HAL
interfaces de rede, definidas como cabeçalhos C em hardware/libhardware
. HIDL
substituímos essas interfaces HAL por interfaces estáveis com controle de versões, que podem
estar em Java (descrito abaixo) ou ser HIDL do lado do cliente e do servidor
em C++.
As interfaces HIDL devem ser usadas principalmente a partir de código nativo e como uma resultado, o HIDL concentra-se na geração automática de código eficiente em C++. No entanto, As interfaces HIDL também precisam estar disponíveis para uso diretamente em Java, uma vez que subsistemas (como a Telefonia) têm interfaces HIDL do Java.
As páginas nesta seção descrevem o front-end do Java para interfaces HIDL, detalhar como criar, registrar e usar serviços, além de explicar como as HALs e as HALs os clientes escritos em Java interagem com o sistema HIDL RPC.
Exemplo de cliente
Este é um exemplo de cliente para uma interface IFoo
no pacote.
android.hardware.foo@1.0
, que está registrado como o nome do serviço
default
e um serviço adicional com o nome de serviço personalizado
second_impl
.
Adicionar bibliotecas
Será necessário adicionar dependências na biblioteca de stubs HIDL correspondente se em que você quer usá-lo. Normalmente, essa é uma biblioteca estática:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Se você já está extraindo dependências dessas bibliotecas, também podem usar a vinculação compartilhada:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Outras considerações para adicionar bibliotecas no Android 10
Se você tiver um app do sistema ou do fornecedor destinado ao Android 10 ou versões mais recentes,
é possível incluir essas bibliotecas estaticamente. Você também pode usar (apenas) classes HIDL
a partir de JARs personalizados instalados no dispositivo com APIs Java estáveis disponibilizadas
usando o mecanismo uses-library
já existente para apps do sistema. A
última abordagem economiza espaço no dispositivo. Para mais detalhes, consulte Como implementar a biblioteca Java SDK. Para
aplicativos mais antigos, o comportamento antigo é preservado.
A partir do Android 10, "superficial" versões dessas bibliotecas
também estão disponíveis. Isso inclui a classe em questão, mas não quaisquer
das classes dependentes. Por exemplo:
android.hardware.foo-V1.0-java-shallow
inclui classes no foo
mas não inclui classes em
android.hidl.base-V1.0-java
, que contém a classe base de todos
HIDL. Se você estiver criando uma biblioteca que já tem a biblioteca
interface disponíveis como dependência, você pode usar o seguinte:
// 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
As bibliotecas de gerenciador e base HIDL também não estão mais disponíveis na inicialização
para apps. Antes, elas às vezes eram usadas como APIs ocultas, devido à
o classloader que prioriza o delegado do Android). Em vez disso, elas foram transferidas
namespace com jarjar
, e os apps que usam esses valores (necessariamente privados
apps) precisam ter cópias separadas. módulos no caminho de classe de inicialização usando
O HIDL deve usar as variantes superficiais dessas bibliotecas Java e adicionar
jarjar_rules: ":framework-jarjar-rules"
para o
Android.bp
para usar a versão dessas bibliotecas que existe
no caminho de classe da inicialização.
Modificar sua fonte Java
Há apenas uma versão (@1.0
) desse serviço, então este código
recupera apenas essa versão. Consulte
extensões de interface
para saber como lidar com várias versões diferentes do serviço.
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(…);
Prestação de serviço
O código do framework em Java pode precisar disponibilizar interfaces para receber chamadas de retorno das HALs.
Para a interface IFooCallback
na versão 1.0 do
android.hardware.foo
, é possível implementar a interface
Java seguindo estas etapas:
- Defina sua interface no HIDL.
- Abrir
/tmp/android/hardware/foo/IFooCallback.java
como de referência. - Crie um novo módulo para a implementação do Java.
- Analise a classe abstrata
android.hardware.foo.V1_0.IFooCallback.Stub
e crie uma nova classe para estendê-la e implementar os métodos abstratos.
Ver arquivos gerados automaticamente
Para conferir os arquivos gerados automaticamente, execute:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Esses comandos geram o diretório
/tmp/android/hardware/foo/1.0
: Para o arquivo
hardware/interfaces/foo/1.0/IFooCallback.hal
, isso gera a
arquivo /tmp/android/hardware/foo/1.0/IFooCallback.java
, que
encapsula a interface Java, o código de proxy e os stubs (tanto proxy como
stubs estão em conformidade com a interface).
-Lmakefile
gera as regras que executam esse comando no build
tempo e permitem que você inclua
android.hardware.foo-V1.0-java
e um link de acordo com o
arquivos adequados. Um script que faz isso automaticamente para um projeto cheio de
interfaces podem ser encontradas em hardware/interfaces/update-makefiles.sh
.
Os caminhos neste exemplo são relativos; hardwares/interfaces podem ser um
na sua árvore de código para que você possa desenvolver uma HAL antes
publicá-lo.
Executar um serviço
A HAL fornece a interface IFoo
, que precisa tornar
para o framework pela interface IFooCallback
. A
A interface IFooCallback
não está registrada pelo nome como detectável
serviço Em vez disso, IFoo
precisa conter um método como
setFooCallback(IFooCallback x)
Para configurar o IFooCallback
da versão 1.0 do
pacote android.hardware.foo
, adicionar
android.hardware.foo-V1.0-java
para Android.mk
. O código
para executar o serviço é:
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);
Extensões de interface
Supondo que um determinado serviço implementa a interface IFoo
em todas
é possível que, em um determinado dispositivo, o serviço forneça
recursos adicionais implementados na extensão de interface
IBetterFoo
, da seguinte forma:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Chamar código ciente da interface estendida pode usar o
Método Java castFrom()
para transmitir com segurança a interface base para o
interface estendida:
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. }