j2emanue j2emanue - 11 months ago 88
Android Question

apt dependency scope in Android gradle - what is it used for?

What is the apt dependency scope in android gradle files i see sometimes ?

An example looks like this?

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 20
buildToolsVersion '20.0.0'
defaultConfig {
applicationId "org.ligboy.test.card.module1"
minSdkVersion 14
targetSdkVersion 20
versionCode 1
versionName "1.0"
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

final DAGGER_VERSION = '2.0.2'

dependencies {
compile "com.google.dagger:dagger:${DAGGER_VERSION}"
apt "com.google.dagger:dagger-compiler:${DAGGER_VERSION}"//what is this scope
provided 'org.glassfish:javax.annotation:10.0-b28'

and in the top level build.gradle file it has this global dependency:

buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'

Notice in the dependencies section there is a apt scope ? i only know of compile, package and provided scope. compile
includes the dependency at compile time and in your package, provided says only include the library at compile time and discard it at
package time so its not included in final build. and Package is the reverse, it includes the dependency in the package and not at compile time.
But what is apt dependency scope which we obviously need the com.neenbedankt.android-apt for it to work so i know its android based.

why cant i use provided dependency scope instead of apt scope ? How do they differ ?

i created a tutorial on dagger dependency scopes for those who need more info.

Answer Source

From the android-apt project page:

The android-apt plugin assists in working with annotation processors in combination with Android Studio. It has two purposes:

  • Allow to configure a compile time only annotation processor as a dependency, not including the artifact in the final APK or library

  • Set up the source paths so that code that is generated from the annotation processor is correctly picked up by Android Studio.

You are using Dagger, which uses annotation processing to generate code. The annotation processing code shouldn't be included in the final APK, and you want the generated code to be visible to Android Studio. android-apt enables this behavior.

This sounds very similar to the provided scope, but apt differs from provided in a few key ways. The first difference is that code generated by an apt dependency is available to the IDE, whereas code generated by a provided dependency is not.

Another important difference is that the code in a library using the provided scope is on the IDE classpath (i.e. you can import the classes and attempt to use them), whereas code in an apt dependency is not. With provided, your code will crash at runtime if you don't actually provide the referenced dependencies with a compile scoped counterpart.

You can find a discussion about apt vs provided on this android-apt issue.

In the case of Dagger, there should be no reason to include the annotation processor and code generator in any of your code (which the provided scope would allow). Thus the apt scope is more appropriate.

Update for October 2016: You probably don't need apt and the android-apt plugin anymore. Version 2.2 of the Android Gradle plugin has an annotationProcessor configuration that you should be using instead.

See more at What's next for android-apt?