tl; dr
Apenas substitua:
compile
com implementation
(se você não precisar de transitividade) ouapi
(se você precisar de transitividade)
testCompile
com testImplementation
debugCompile
com debugImplementation
androidTestCompile
com androidTestImplementation
compileOnly
ainda é válido. Foi adicionado no 3.0 para substituir o fornecido e não compilar. ( provided
introduzido quando Gradle não tinha um nome de configuração para esse caso de uso e o nomeou após o escopo fornecido pelo Maven.)
É uma das mudanças que estão chegando com o Gradle 3.0 que o Google anunciou no IO17 .
A compile
configuração agora está obsoleta e deve ser substituída por implementation
ouapi
Na documentação do Gradle :
dependencies {
api 'commons-httpclient:commons-httpclient:3.1'
implementation 'org.apache.commons:commons-lang3:3.5'
}
As dependências que aparecem nas api
configurações serão expostas transitivamente aos consumidores da biblioteca e, como tal, aparecerão no caminho de classe de compilação dos consumidores.
As dependências encontradas na implementation
configuração, por outro lado, não serão expostas aos consumidores e, portanto, não vazarão no caminho de classe de compilação dos consumidores. Isso vem com vários benefícios:
- dependências não vazam mais no caminho de classe de compilação dos consumidores, portanto você nunca dependerá acidentalmente de uma dependência transitiva
- compilação mais rápida graças ao tamanho reduzido do caminho de classe
- menos recompilações quando as dependências da implementação mudam: os consumidores não precisariam ser recompilados
- publicação mais limpa: quando usadas em conjunto com o novo plug-in maven-publish, as bibliotecas Java produzem arquivos POM que distinguem exatamente entre o que é necessário para compilar na biblioteca e o que é necessário para usar a biblioteca em tempo de execução (em outras palavras, não misture o que é necessário para compilar a própria biblioteca e o que é necessário para compilar na biblioteca).
A configuração de compilação ainda existe, mas não deve ser usada, pois não oferecerá as garantias que as configurações api
e implementation
fornecem.
Nota: se você estiver usando apenas uma biblioteca em seu módulo de aplicativo, o caso comum, não notará nenhuma diferença.
você verá a diferença apenas se tiver um projeto complexo com módulos dependendo um do outro ou se estiver criando uma biblioteca.
implementation
ocultar a dependência. Minha pergunta faz sentido?implementation
apenas x api será exposto, mas se você usarapi
y, z também será exposto.Esta resposta vai demonstrar a diferença entre
implementation
,api
ecompile
em um projeto.Digamos que eu tenho um projeto com três módulos Gradle:
app
temmyandroidlibrary
como dependências.myandroidlibrary
temmyjavalibrary
como dependências.myjavalibrary
tem umaMySecret
classemyandroidlibrary
temMyAndroidComponent
classe que manipula valor daMySecret
classePor fim,
app
está interessado apenas no valor demyandroidlibrary
Agora, vamos falar sobre dependências ...
app
precisa consumir:myandroidlibrary
, portanto, noapp
uso build.gradleimplementation
.( Nota : você também pode usar api / compile. Mas mantenha esse pensamento por um momento.)
Como você acha que o
myandroidlibrary
build.gradle deve ser? Qual escopo devemos usar?Temos três opções:
Compilar ou API (opção 2 ou 3)
Se você estiver usando
compile
ouapi
. Nosso aplicativo Android agora pode acessar amyandroidcomponent
dependência, que é umaMySecret
classe.Implementação (opção 1)
Se você estiver usando a
implementation
configuração,MySecret
não será exposto.Então, qual configuração você deve escolher? Isso realmente depende da sua exigência.
Se você deseja expor dependências, use
api
oucompile
.Se você não deseja expor dependências (ocultando seu módulo interno), use
implementation
.Nota:
Esta é apenas uma essência das configurações de Gradle, consulte a Tabela 49.1. Plug-in da Biblioteca Java - configurações usadas para declarar dependências para obter explicações mais detalhadas.
O projeto de amostra para esta resposta está disponível em https://github.com/aldoKelvianto/ImplementationVsCompile
fonte
compile
não garante as mesmas coisas queapi
garante.Compile
A configuração foi descontinuada e deve ser substituída porimplementation
ouapi
.Você pode ler os documentos em https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation .
A breve parte sendo
Para mais explicações, consulte esta imagem.
fonte
Breve solução:
A melhor abordagem é substituir todas as
compile
dependências porimplementation
dependências. E somente onde você vazar a interface de um módulo, você deve usarapi
. Isso deve causar muito menos recompilação.Explique mais:
Antes do plugin Android Gradle 3.0 : tivemos um grande problema: uma alteração de código faz com que todos os módulos sejam recompilados. A causa raiz disso é que Gradle não sabe se você vazou a interface de um módulo através de outro ou não.
Após o Android Gradle plugin 3.0 : o mais recente plugin do Android Gradle agora exige que você defina explicitamente se você vaza a interface de um módulo. Com base nisso, ele pode fazer a escolha certa sobre o que deve recompilar.
Como tal, a
compile
dependência foi descontinuada e substituída por duas novas:api
: você vaza a interface deste módulo através de sua própria interface, o que significa exatamente o mesmo que acompile
dependência antigaimplementation
: você só usa este módulo internamente e não o vaza pela interfacePortanto, agora você pode dizer explicitamente à Gradle para recompilar um módulo se a interface de um módulo usado mudar ou não.
Cortesia do blog Jeroen Mols
fonte
fonte
implementation
seguido por umruntime
.A breve diferença no termo do leigo é:
leia a resposta de @aldok para um exemplo abrangente.
fonte
Desde a versão 5.6.3, a documentação do Gradle fornece regras simples para identificar se uma
compile
dependência antiga (ou nova) deve ser substituída por umaimplementation
ou umaapi
dependência:fonte
Gradle 3.0
introduziu as próximas mudanças:compile
->api
api
palavra-chave é igual a obsoletacompile
compile
->implementation
É preferível , pois tem algumas vantagens.
implementation
expor a dependência apenas para um nível acima no tempo de construção (a dependência está disponível no tempo de execução). Como resultado, você tem uma construção mais rápida (não é necessário recompilar os consumidores com mais de 1 nível)provided
->compileOnly
Essa dependência está disponível apenas em tempo de compilação (a dependência não está disponível no tempo de execução). Essa dependência não pode ser transitiva e ser
.aar
. Ele pode ser usado com o processador de anotação em tempo de compilação e permite reduzir um arquivo de saída finalcompile
->annotationProcessor
Muito semelhante,
compileOnly
mas também garante que a dependência transitiva não é visível para o consumidorapk
->runtimeOnly
A dependência não está disponível em tempo de compilação, mas disponível em tempo de execução.
fonte
api = public
,implementation = internal
ecompileOnly = private
- eu preciso para criar esses aliases para estas funções como eles são super confuso.