Android AIDL

Comunicação entre Aplicativos DIFERENTES

Paulo Linhares
9 min readAug 31, 2017

Precisa que sua aplicação Android se comunique (passar/receber) informações para outras aplicações ? Para isso, o Android lhe fornece o conceito de AIDL.

Existe outra forma de passar dados para outros packages, conhecidos no Android como intent filter profundos, que é o que chamamos de Deep Links. Porém neste post, vamos nos ater exclusivamente ao método AIDL para comunicação entre Aplicativos Android.

Atenção: Tenha em mente que AIDL não é um tipo de Deep Links. Embora, tenham algumas semelhanças em suas finalidades, o conceito técnico entre ambos é bem distante. Deep Links são baseados em endpoints (URI) para Intents Filter profundo, muito mais parecido com uma experiência WEB. Enquanto que AIDL é baseado em Interfaces e se dá num nível mais baixo do sistema envolvendo seus processos.

Mas o que é de fato AIDL ?

Entendendo AIDL

Em computação, um sistema operacional precisa oferecer em sua arquitetura a possibilidade de aplicações se comunicarem entre si. Isso é conhecido como IPC (inter communication process) — no bom português: Comunicação Entre Processos.

Por questões de segurança, performance e da “fé dos sete reinos” , o Android executa cada aplicação em um processo separado. Assim, um aplicativo não pode acessar o processo de outro aplicativo se o mesmo não possuir uma “assinatura” para tal. A essa assinatura, no Android em especial, damos o nome de AIDL.

Então, AIDL nada mais é que uma abordagem IPC do mundo da computação, criada pelo Google para facilitar a vida de nós desenvolvedores Android. Sem AIDL no framework Android, teríamos que desenvolver todas as implementações para permitir essa comunicação entre processos, um trabalho nada trivial.

Conhecendo AIDL

AIDL é um acrônimo para Android Interface Definition Language. E é com ela que conseguimos de forma simples fazer com que aplicativos se comuniquem entre si acessando o processo um do outro, como Cliente/Servidor.

Em que casos irei precisar implementar AIDL em meu Aplicativo ?

  • Semáforo:

Você pode usar AIDL para criar um sistema de semáforo, baseado em aplicativo Android, para um cruzamento de quatro tempos, por exemplo.

Logo, você precisaria de quatros devices (celulares) em rede — com android. Mas para fins didáticos, vamos desconsiderar isso e imaginar que os quatros semáforos (Aplicativos) estão em um mesmo device.

Então seu APP para este projeto possui apenas uma MainActivity simulando em sua View um semáforo tradicional (luz vermelha, amarela e verde). Imagine que você tenha criado quatro Aplicativos com a mesma funcionalidade, obviamente com packages diferentes e, que por padrão você codificou para que cada APP abra com o sinal vermelho ativo. Mas agora você precisa gerenciar isso, passar comandos/receber informações para os outros Semáforos(outros APPs). É aqui que entra em cena AIDL, que através de suas Interfaces e assinaturas irá possibilitar com que você possa apontar para qual Semáforo precisa mudar seu status de vermelho para verde, e esse por sua vez passar, após determinado tempo, para status amarelo e, em seguida chamar o próximo semáforo da vez para ficar com status verde.

Talvez você nunca precise de algo assim, mas dei esse exemplo para você saber do poder que AIDL lhe fornece no Android.

  • Calculadora

Uma abordagem mais comum com uso de AIDL, é um projeto baseado em módulos, as vezes determinado projeto precisa implementar sua lógica em aplicativos separados que se complementam. Imagine que sua empresa possua um ERP (Enterprise Resource Planning) em um Aplicativo e, que tenha surgido a necessidade do financeiro da mesma fazer um cálculo pesado de juros compostos com taxas, etc. E que sua empresa já possua um outro APP que já faça esse tipo de cálculo. Então, ao invés de duplicar esse código da Calculadora para dentro do ERP ou para uma Library, você pode usar AIDL e fazer seu ERP solicitar que seu APP de Calculadora faça o trabalho pesado e retorne no final o valor do resultado do cálculo. Esse é o exemplo mais típico de uso da AIDL Android, conhecida como abordagem Client/Server.

Vamos colocar a mão na massa agora ?

1- Comece criando um Aplicativo normalmente no Android Studio, escolha o nome do package. No meu caso ficou br.com.packapps.aidlservercalculator.

2- Com APP criado, crie dentro do diretório principal /app um arquivo .aidl :

Escolha o nome para seu arquivo que será criado. O meu ficou assim:

Um arquivo com extensão .aidl será criado:

Repare que por padrão o Android Studio já nos gera uma pequena implementação de exemplo de uso, o método basicTypes(…) (linha 11) . Isso não é à toa, na verdade o Android Studio está lhe mostrando quais o tipos de dados é permitido trafegar pela interface AIDL — repare que todos os parâmetros são primitivos. Você também pode trafegar objetos Parcelable, deixarei o link da documentação do Android Developer para você dá uma olhada depois.

Um objeto Parcelable é uma implementação que converte um objeto qualquer em dados primitivos para possibilitar seu transporte na arquitetura de uma máquina. Lembre-se que o método IPC em computação permite por padrão apenas tráfego de dados primitivos. E Parcelable é uma forma de contornar isso no Android. Porém você não deve confundir Parcelable com Serializable.

Editei nosso método para fazer apenas uma operação de soma, mas você pode criar quantos métodos desejar em sua interface. Ficou assim:

Feita as modificações, é hora de compilar seu projeto. Isso é indispensável! E você entenderá o porquê jaja.

Ao compilar seu projeto, é gerado um arquivo de interface .java com mesmo nome do seu arquivo .aidl. Esta interface contém uma subclass chamada Stub que se trata de uma implementação da interface pai. Mostrarei um pouco deste arquivo apenas para fins de compreensão:

Este arquivo .java é oculto por padrão em seu projeto, então não se preocupe por não o estar vendo. Daqui a pouco você terá oportunidade vê-lo em seu projeto.

3. O último passo, é expor sua interface AIDL a seus clientes que desejarão comunicar-se com seu Aplicativo. Para isso precisamos criar uma implementação da subclass Stub que o Android Studio SDK gerou automaticamente pra nós— mostrado acima.

Antes de fazermos essa implementação, crie um Service em seu projeto e dê a ele o nome que desejar. O meu ficou assim:

A implementação acima foi gerada automaticamente pelo Android Studio.

Agora precisamos criar uma class que extends a subclass Stub Criada automaticamente, como explicado acima.

Vamos fazer isso dentro de nosso service: MyServiceAidl:

Repare que o método @Override onBind da nossa Service retorna um objeto IBinder. Por padrão a subclass Stub extends Binder que por sua vez implements IBinder.

Ficou confuso? Veja por si mesmo, coloque o cursor do mouse na class Stub e dê um Command + b (Mac OS). Faça o mesmo nos extends e implements, e você entenderá melhor o polimorfismo por trás de toda a implementação.

Logo podemos fazer nosso método onBind(…) da nossa Service MyServiceAidl retornar nossa subclass que acabamos de criar. Ficando assim:

Atente que instanciamos uma referência da nossa nova subclass MyIBind na linha 3. E modificamos o retorno do método onBind(…) de Service para retorna nossa instância de MyIBind na linha 10.

4. Com a implementação pronta em nossa service, agora só precisamos criar um intent-filter em nossa service no Manifest para permitir uma chamada implícita à service pelo nosso Client que assinar nossa AIDL. Deixe assim:

Pronto, é isso! Seu Aplicativo Server AIDL está pronto. Agora é só assinar a interface AIDL em outro(s) Aplicativo(s) para ter acesso ao(s) método(s) da mesma.

Todos os artigos que li até agora, mostram exemplos de assinatura dentro do mesmo package (mesmo aplicativo). Isso não é muito útil visto que o intuito de usar AIDL é justamente possibilitar comunicação entre processos diferentes — No Android significa packages diferentes. E mais, quando fui fazer uso de AIDL entre dois APPs obtive uma serie de problemas que tive que resolver na velha astúcia de desenvolvedor, pois em alguns pontos a documentação não é bem clara.

Criando APP Client

Então, agora vamos criar um novo Aplicativo que irá trabalhar como Aplicativo Client. É neste aplicativo que vamos assinar a interface AIDL do Aplicativo Server que acabamos de criar acima.

1- Crie um Aplicativo normalmente no Android Studio. O meu package ficou br.com.packapps.aidlclientcalculator

2- Da mesma forma que criou um arquivo .aidl no APP acima, crie neste também.

Com o arquivo criado, copie o conteúdo do arquivo .aidl do APP Server do qual deseja assinar a AIDL.

E Atenção: seu arquivo .aidl do APP Client deve ficar EXATAMENTE igual ao .aidl do APP Server

Aqui vem o primeiro problema que enfrentei e que você não irá achar na documentação.

Repare que quando você cria um arquivo .aidl o Android Studio cria dentro do diretório /aidl um package comprimido que recebe a mesma escrita do package da sua Aplicação: br.com.packapps.aidlclientcalculator. Esse é o problema, desta forma você esta criando outro aplicativo com papel de Server AIDL e não um Aplicativo Client com assinatura de AIDL de outro APP.

Então vamos corrigir isso! Altere este package dentro de /aidl para exatamente o package do Aplicativo Server que você deseja assinar a interface. No Android Studio, comece descomprimindo o nome do package para posteriormente renomea-lo:

Selecione o package dentro de aidl/. Clique no ícone da engrenagem e desmarque a opção Compact Empty Middle Packages:

3. Renomeie o package

Na caixa de dialogo seguinte, clique em Rename directory e dê exatamente o nome do package do APP Server que criamos acima.

Marque novamente Compact Empty Middle Packages para compactar a visualização no seu Android Studio. O meu ficou assim:

4. Agora reconstrua seu projeto para que o Android Studio possa trabalhar na implementação das classes que serão geradas automaticamente.

Teoricamente tudo agora está corretamente configurado para seu APP Client fazer uma chamada para seu APP Server. Então vamos fazer essa implementação em nossa MainActivity.java:

5. Crie uma instancia do seu arquivo IMyAidlInterface.java que o Android Studio criou automaticamente baseado em seu IMyAidlInterface.aidl.

Você vai precisar criar uma instância de ServiceConnection para permitir a comunicação ao service do APP Server que detém a AIDL. Veja:

ServiceConnection é uma interface que permite comunicação entre Services de aplicativos. Existem dois métodos que precisamos sobrescrever, o mais importante deles é o onServiceConnection(…), que é onde criamos uma instância da subclass Stub — que explicarei em breve.

Tenha em mente que os métodos de ServiceConnection são callbacks e rodam na Thread principal do seu APP.

Em onServiceConnected(…) (Linha 16) instanciamos nosso objeto de IMyAidlInterface.java com o método static de Stub: asInterface(…). Isso retorna à nossa instância o objeto mBinder. A grosso modo, estamos espelhando o objeto mBinder como parâmetro no callback onServiceConnected(…).

Com nosso objeto iMyAidlInterface devidamente instanciado, vamos criar nossa Intent que conterá a chamada ao Service do APP Server:

Lembra que criamos uma <intent-filter> em nosso service no APP Server ? Então, é com ela que criamos nossa chamada implícita de Intent (linha 29), passando o package do APP Server como parâmetro (linha 30):

Intent intent = new Intent("br.com.packapps.aidlservercalculator.CALCULATE");
intent.setPackage("br.com.packapps.aidlservercalculator");

Agora estamos pronto para usar os métodos da interface AIDL assinada. Criei uma action com FloatingActionButton apenas para simular um clique de soma.

Também criei uma view no APP para simular uma tela de calculadora simples, adicionei alguns widgets como EditText e TextView, mas que não convém mostrar aqui esse código, pois este não é nosso foco. — E acredito que pela simplicidade você terá problemas com isso.

Finalmente estamos prontos para testar nossos projetos.

Tudo funcionando conforme desejado \0/.

Espero ter conseguido compartilhar um pouco de experiência com você. Até a próxima. Fuiiiii.

Repositórios dos projetos deste post:

Links úteis:

--

--

Paulo Linhares

Android Developer at SKY, Santander | Superdigital , Iterative | Posto Ipiranga, YetGo, MelhorCorrida, Packapps…