Estou tentando descobrir qual é a diferença entre api
e implementation
configuração ao criar minhas dependências.
Na documentação, ele diz que implementation
tem melhor tempo de construção, mas, vendo esse comentário em uma pergunta semelhante, fiquei me perguntando se isso é verdade.
Como não sou especialista em graduação, espero que alguém possa ajudar. Eu já li a documentação, mas estava pensando em uma explicação fácil de entender.
android
gradle
dependencies
implementation
reinaldomoreira
fonte
fonte
compile
paraapi
. As bibliotecas usadas internamente podem usar algumas implementações privadas que não são expostas na biblioteca final para que sejam transparentes para você. Essas dependências "interno-privadas" podem ser alteradasimplementation
e, quando o plug-in do Android gradle compilar seu aplicativo, ele ignorará a compilação dessas dependências, resultando em um tempo de compilação menor (mas essas dependências estarão disponíveis no tempo de execução). Obviamente, você pode fazer a mesma coisa se você tem bibliotecas de módulos locaisRespostas:
A
compile
palavra-chave Gradle foi descontinuada em favor das palavras-chaveapi
eimplementation
para configurar dependências.Usar
api
é o equivalente a usar o obsoletocompile
, portanto, se você substituir todoscompile
porapi
tudo, tudo funcionará como sempre.Para entender a
implementation
palavra - chave, considere o seguinte exemplo.EXEMPLO
Suponha que você tenha uma biblioteca chamada
MyLibrary
que internamente use outra biblioteca chamadaInternalLibrary
. Algo assim:Suponha que a configuração de
MyLibrary
build.gradle
usos seja assim:api
dependencies{}
Você deseja usar
MyLibrary
no seu código e, no aplicativo,build.gradle
adicionar esta dependência:Usando a
api
configuração (ou obsoletacompile
), você pode acessarInternalLibrary
no código do seu aplicativo:Dessa maneira, o módulo
MyLibrary
está potencialmente "vazando" a implementação interna de algo. Você não deve poder usá-lo porque não é importado diretamente por você.A
implementation
configuração foi introduzida para evitar isso. Portanto, agora se você usaimplementation
em vez deapi
emMyLibrary
:você não poderá mais acessar
InternalLibrary.giveMeAString()
o código do seu aplicativo.Esse tipo de estratégia de boxe permite que o plug-in Android Gradle saiba que, se você editar algo
InternalLibrary
, ele deve acionar a recompilaçãoMyLibrary
e não a recompilação de todo o aplicativo, porque você não tem acessoInternalLibrary
.Quando você tem muitas dependências aninhadas, esse mecanismo pode acelerar muito a compilação. (Assista ao vídeo no final do link para uma compreensão completa disso)
CONCLUSÕES
Ao mudar para o novo plug-in Android Gradle 3.XX, você deve substituir todo o seu
compile
pelaimplementation
palavra - chave (1 *) . Em seguida, tente compilar e testar seu aplicativo. Se tudo estiver ok, deixe o código como está, se você tiver problemas, provavelmente há algo errado com suas dependências ou usou algo que agora é privado e não é mais acessível. Sugestão do engenheiro de plug-in Android Gradle Jerome Dochez (1 ) * )Se você é um mantenedor de biblioteca, deve usar
api
para todas as dependências necessárias para a API pública da sua biblioteca, enquanto usaimplementation
para dependências de teste ou dependências que não devem ser usadas pelos usuários finais.Artigo útil Mostrando a diferença entre implementação e API
REFERÊNCIAS (este é o mesmo vídeo dividido para economizar tempo)
E / S do Google 2017 - Como acelerar a construção do Gradle (VÍDEO COMPLETO)
Google I / O 2017 - Como acelerar a criação do Gradle (SOMENTE NOVA GRADLE PLUGIN 3.0.0)
Google I / O 2017 - Como acelerar a criação do Gradle (referência a 1 * )
Documentação do Android
fonte
MyLibrary#myString()
falha porque o ProGuard foiInternalLibrary
removido. Qual é a melhor prática para que as libs do Android sejam usadas nos aplicativos ProGuard?Eu gosto de pensar em uma
api
dependência como pública (vista por outros módulos) enquanto aimplementation
dependência como privada (vista somente por este módulo).Observe que diferentemente de
public
/private
variáveis e métodosapi
/implementation
dependências não são impostos pelo tempo de execução. Isso é apenas uma otimização em tempo de construção, que permiteGradle
saber quais módulos ele precisa recompilar quando uma das dependências altera sua API.fonte
api
dependências no escopo "compilação" (elas serão incluídas como dependências na sua biblioteca e tudo o que depende da sua biblioteca) eimplementation
dependências no escopo "tempo de execução" (é melhor que estejam no diretório classpath quando seu código estiver em execução, mas eles não são necessários para compilar outro código que usa sua biblioteca).implementation
para qualquer dependência necessária para executar (e para a sua biblioteca compilar), mas isso não deve ser automaticamente puxado para projetos que usam sua biblioteca. Um exemplo seria jax-rs, sua biblioteca pode usar RESTeasy, mas não deve puxar essas bibliotecas para qualquer projeto que use sua biblioteca, pois elas podem usar Jersey.Considere que você possui um
app
módulo que usalib1
como biblioteca elib1
usalib2
como biblioteca. Algo parecido com isto:app -> lib1 -> lib2
.Agora, ao usar
api lib2
inlib1
, éapp
possível verlib2
códigos ao usar:api lib1
ouimplementation lib1
noapp
módulo.Mas quando se utiliza
implementation lib2
emlib1
, entãoapp
não pode ver oslib2
códigos.fonte
As respostas do @matpag e do dev-bmax são claras o suficiente para fazer as pessoas entenderem usos diferentes entre implementação e API. Eu só quero fazer uma explicação extra de outro ângulo, na esperança de ajudar as pessoas que têm a mesma pergunta.
Criei dois projetos para teste:
A hierarquia de dependências descrita acima se parece com:
[project-b] -> [project-a] -> [spring-boot-gradle-plugin]
Depois testei os seguintes cenários:
Tornar o projeto A depende de 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' pela implementação .
Execute o
gradle dependencies
comando em um terminal no diretório raiz do poject B , com a captura de tela da saída a seguir. Podemos ver que 'spring-boot-gradle-plugin' aparece na árvore de dependências runtimeClasspath, mas não na compileClasspath, acho que é exatamente por isso que não podemos criar uso de biblioteca que declarou usando implementação, simplesmente não será através de compilação.O projeto A depende do 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' da api
Execute o
gradle dependencies
comando em um terminal no diretório raiz do poject B novamente. Agora 'spring-boot-gradle-plugin' aparece na árvore de dependências compileClasspath e runtimeClasspath.Uma diferença significativa que notei é que a dependência no projeto produtor / biblioteca declarada no modo de implementação não aparecerá no compileClasspath de projetos do consumidor, para que não possamos usar a lib correspondente nos projetos do consumidor.
fonte
Da documentação gradle :
Vamos dar uma olhada em um script de construção muito simples para um projeto baseado em JVM.
fonte