The docs mention that implementation provides significant build time improvements over compile/api. What about compileOnly?
My use case is a multi-module (sorry I don't like Gradle's multi-project terminology) project, where I have an Android app, and multiple libraries that the app depends on (implementation). Some of the libraries also depend on one another. Should I use implementation or compileOnly when declaring dependencies in the library modules? My app module will be using implementation to depend on those artifacts, so I don't need them to be transitive through the library modules.
The api configuration should be used for dependencies that are exported to external modules (transitive dependency). Vice-Versa implementation configuration should be used for dependencies that are internal to the component (not transitive dependency).
implementation vs compileOnly:
There is no similarity in their job, compileOnly is
a configuration inherited from java-plugin
required at compile time
also not included in the runtime classpath or exposed to dependent
projects.
So compileOnly doesn't replace the implementation configuration job e.g:
implementation 'com.android.support:appcompat-v7:25.1.0' // can't use compileOnly here
testCompile 'junit:junit:4.12'
compile "com.google.dagger:dagger:2.8" // can't use here also
annotationProcessor "com.google.dagger:dagger-compiler:2.8" // can't use here also
compileOnly 'javax.annotation:jsr250-api:1.0' // we can use compileOnly here because it's required on run time only.
Since your case is a "multi-module", you have to use the api configuration, until you reach the final module it's better to use implementation.
Following graph describe those configurations:
Performance?
I think api requires more memory because gradle will snapshot every class in that transitive module, vice versa implementation is a preferred configuration because (as mentioned above) it's used for its own internal implementations.
Related
I'm learning developing app for android. In particular, how it works a mediaplayer. The target system should be android for automotive. For this reason I have downloaded a sample UAMP application from google but, unfortunately, doesn't compile, it is too old. So I decided to rebuild a project and importe all the modules. For me is important understand how it works! Anyway, I have imported all libraries, in gradle and in the modules, I have compiled the automotive version of the app and I have this message:
*The given artifact contains a string literal with a package reference 'android.support.v4' that cannot be safely rewritten. Libraries using reflection such as annotation processors need to be updated manually to add support for androidx*.
In detail, the gradle explains:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':automotive:mergeDebugJavaResource'.
Could not resolve all files for configuration ':automotive:debugRuntimeClasspath'.
Failed to transform kotlin-android-extensions-1.3.41.jar (org.jetbrains.kotlin:kotlin-android-extensions:1.3.41) to match attributes {artifactType=android-java-res, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
> Execution failed for JetifyTransform: C:\Users\James Tiberius Kirk\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-android-extensions\1.3.41\3bb1958b60435763b1299eb4e2dea5bea3bab2a3\kotlin-android-extensions-1.3.41.jar.
> Failed to transform 'C:\Users\James Tiberius Kirk\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-android-extensions\1.3.41\3bb1958b60435763b1299eb4e2dea5bea3bab2a3\kotlin-android-extensions-1.3.41.jar' using Jetifier. Reason: AmbiguousStringJetifierException, message: The given artifact contains a string literal with a package reference 'android.support.v4' that cannot be safely rewritten. Libraries using reflection such as annotation processors need to be updated manually to add support for androidx.. (Run with --stacktrace for more details.)
This is a known exception, and Jetifier won't be able to jetify this library.
>
Ok, sorry for my poor english, but the problem is quite complex and my english is not so advanced. The project for automotive is composed by three branches, the mobile app, the automotive app and a shared branch. Now I am working on the automotive branch, and its includes the shared branch.
The first thing I did was check if may be one or more included libraries were not the last release. And as I can understand all the libraries are the last version and compatible with androidx (my target system) here the list of include libraries on the Automotive branch:
>
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.72"
implementation "androidx.core:core-ktx:1.2.0"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.appcompat:appcompat:1.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.preference:preference:1.1.1"
androidTestImplementation "androidx.test.ext:junit:1.1.1"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
implementation "com.google.android.exoplayer:extension-mediasession:2.11.4"
implementation "com.google.android.exoplayer:exoplayer-core:2.11.4"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7'
implementation "com.github.bumptech.glide:glide:4.11.0"
implementation "com.google.gms:google-services:4.3.3"
implementation 'com.google.android.gms:play-services-drive:17.0.0'
implementation 'com.google.android.gms:play-services-auth:18.0.0'
implementation 'com.google.apis:google-api-services-gmail:v1-rev72-1.23.0'
implementation 'com.google.android.material:material:1.2.0-alpha06'
implementation project(path: ':shared')
}
In the shared branch the included libraries are:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.72"
implementation 'androidx.media:media:1.1.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "com.google.android.exoplayer:extension-mediasession:2.11.4"
implementation "com.google.android.exoplayer:exoplayer-core:2.11.4"
implementation "com.google.android.exoplayer:exoplayer-dash:2.11.4"
implementation "com.google.android.exoplayer:exoplayer-ui:2.11.4"
implementation "com.google.android.exoplayer:exoplayer-hls:2.11.4"
implementation "com.google.android.exoplayer:exoplayer-smoothstreaming:2.11.4"
implementation "com.github.bumptech.glide:glide:4.11.3"
}
So, I have tryed any thing I know, but the issue is still there. Is there anyone, that can give me a suggestion, an Idea, something that can help me to solve this problem and proceed on the training?
Thanks a lot for any contribute.
The UAMP version1 is not supported anymore, and will not work because a lot of things in it are deprecated. my advice is don't import the project and change it. you need to build your own from the ground up.
Trying to integrate instant search in my Android app, but "Searcher" is unresolved.
I have the following dependencies currently, am I missing any?
implementation "com.algolia:algoliasearch-android:3.27.0"
implementation "com.algolia:algoliasearch-client-kotlin-jvm:1.0.0"
implementation 'com.algolia:instantsearch-androidx:1.15.2'
implementation "io.ktor:ktor-client-android:1.2.2"
include core dependency also
implementation 'com.algolia:instantsearch-androidx-core:1.15.2'
The latest release of instantsearch-androidx is lacking its transitive dependencies. The issue was reported on GitHub, you can follow its progress there - likely a new version will soon be released with the appropriate dependencies packaged.
As a workaround, you can add the dependencies yourself to your application - depending on the InstantSearch features you use, you might need some or all of the following:
implementation "com.algolia:instantsearch-androidx:$VERSION_INSTANTSEARCH"
implementation "com.algolia:instantsearch-androidx-core:$VERSION_INSTANTSEARCH"
implementation 'com.algolia:algoliasearch-android:3.27.0'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation 'com.github.bumptech.glide:glide:4.7.1'
I have seen the following different ways of writing the dependencies in Gradle:
implementation("com.squareup.okhttp3:okhttp:3.12.0")
and
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
and
compile 'com.squareup.okhttp3:okhttp:3.12.0'
Are they all different ways to accomplish the same thing or are there differences among them?
build.gradle files are just Groovy scripts. So its syntax applies here
In Groovy, you can ignore the parenthesis when invoking a function so
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
is actually equivalent to
implementation('com.squareup.okhttp3:okhttp:3.12.0')
In Groovy you also have GStrings which are represented by ". They contains embedded Strings. In that particular case you're not interpolating any value so both
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
and
implementation "com.squareup.okhttp3:okhttp:3.12.0"
are equivalent. Beware that if you wanted to interpolate some value you'd do
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion" // this line works
implementation 'com.squareup.okhttp3:okhttp:$okhttpVersion' // this line doesn't work
compile method for defining dependencies is deprecated in favor of implementation and api. You can find more info here. You can consider that if you're exposing somehow the classes of your dependencies you'll use api but if you're using the dependencies internally implementation is fine
the compile configuration is deprecated and is replaced by implementation or api.
At first, I am using a single module app for the the Android Application, but now I want to separate the module into app module (core-business logic and UI) and libraries module (HTTP-related and base abstract classes).
I made new libraries module as the library module and start moving some utility code from app to libraries but problem comes. The problem is, I want my app to use the dependency used in libraries module without having to include same dependency in both build.gradle.
In my app module, I want my source code to use the RecyclerView and Retrofit defined in libraries, but I can't do it unless I also include retrofit and recyclerview-v7 in my app/build.gradle.
app/main/src/..../HomeActivity.kt
var gridDataset: RecyclerView? = null // RecyclerView not found in classpath
app/build.gradle
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":libraries")
libraries/build.gradle
implementation "com.android.support:recyclerview-v7:$support_library_version"
implementation "com.squareup.retrofit2:retrofit:2.4.0"
implementation "com.squareup.retrofit2:converter-gson:2.4.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
implementation "com.squareup.okhttp3:logging-interceptor:3.8.0"
Where did I go wrong? Or is it simply impossible to do that?
specify your dependencies in libraries/build.gradle using api instead of implementation
This should add these dependencies to the class path for any module depending on your libraries module
api "com.android.support:recyclerview-v7:$support_library_version"
api "com.squareup.retrofit2:retrofit:2.4.0"
api "com.squareup.retrofit2:converter-gson:2.4.0"
api "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
api "com.squareup.okhttp3:logging-interceptor:3.8.0"
I try to use Dagger2 in my Android project;
When I use apt, every things is right.But apt is not supported in AndroidStudio 3.0, so I use annotation processor.But no Dagger2 code created after I click "Make Project";
And I'm sure the annotetion processing is enable in AndroidStudio,because the Butterknife annotation processor is all right.
the follow is the build.gradle:
dependencies {
annotationProcessor 'com.google.dagger:dagger-android-processor:2.13'
compile 'com.google.dagger:dagger-android:2.13'
compile 'com.google.dagger:dagger-android-support:2.13'
compile 'com.jakewharton:butterknife:8.6.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
}
use this in android studio 3.0 version
implementation 'com.google.dagger:dagger:2.9'
annotationProcessor 'com.google.dagger:dagger-compiler:2.9'
these are the dependences for dagger2 and butter in andriod studio 3.0
//ButterKniffe
compile "com.jakewharton:butterknife:8.8.1"
kapt "com.jakewharton:butterknife-compiler:8.8.1"
//dagger
compile "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
It is one of the breaking changes coming with gradle:3.0 that Google announced at IO17 gradle:3.0
the compile configuration is now deprecated and should be replaced by implementation or api
From the gradle docs :
Dependencies appearing in the api configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers.
Dependencies found in the implementation configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath. This comes with several benefits:
List item dependencies do not leak into the compile classpath of consumers anymore, so you will never accidentally depend on a transitive dependency
faster compilation thanks to reduced classpath size
less recompilations when implementation dependencies change: consumers would not need to be recompiled
cleaner publishing: when used in conjunction with the new maven-publish plugin, Java libraries produce POM files that distinguish exactly between what is required to compile against the library and what is required to use the library at runtime (in other words, don't mix what is needed to compile the library itself and what is needed to compile against the library).
The compile configuration still exists but should not be used as it will not offer the guarantees that the api and implementation configurations provide.