Failed to implement androidx lifecycle dependencies - android-studio

I'm learning to use Android Studio, when I want to implement the lifecycle dependencies in Gradle, an error message appears after the sync. I don't understand why, but I did everything as indicated in the Android Studio documentation.
Do you have any idea where my mistake is?enter image description here
val lifecycle_version = "2.5.1"
val arch_version = "2.1.0"
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
// ViewModel utilities for Compose
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version")
// LiveData
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
// Lifecycles only (without ViewModel or LiveData)
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version")
// Saved state module for ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
// Annotation processor
kapt("androidx.lifecycle:lifecycle-compiler:$lifecycle_version")
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
// optional - helpers for implementing LifecycleOwner in a Service
implementation("androidx.lifecycle:lifecycle-service:$lifecycle_version")
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation("androidx.lifecycle:lifecycle-process:$lifecycle_version")
// optional - ReactiveStreams support for LiveData
implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version")
// optional - Test helpers for LiveData
testImplementation("androidx.arch.core:core-testing:$arch_version")
// optional - Test helpers for Lifecycle runtime
testImplementation ("androidx.lifecycle:lifecycle-runtime-testing:$lifecycle_version")

Just replace val with def.
In my case, it is working.

Related

Kotlin / Gradle DSL integration to manage dependency version variables

Kotlin / Gradle DSL integration to manage dependency version variables
My question is about the best way to manage dependency version variables in IntelliJ Idea / Android Studio using Gradle
Kotlin DSL
The secondary purpose is to have the IDE perform version upgrades upon clicking the suggestion to change to newer
version automatically instead of manually editing the versioning file entry.
the simple way
definition
build.gradle.kts
plugins {
application
kotlin("jvm") version "1.7.10"
}
dependencies {
implementation("io.ktor:ktor-server-core-jvm:2.1.1")
}
Comments
This is working but "clumsy" and does not comply to single source of truth (SSOT)
I have seen several ways that attempt having a SSOT for the dependency versions
by Project
Definition
gradle.properties
ktor_version = 2.1.0
kotlin_version = 1.7.10
build.gradle.kts
val ktor_version: String by project // NOTE the complaint Property name 'ktor_version' should not contain underscores
val kotlin_version: String by project
plugins {
application
kotlin("jvm") version "1.7.10" // NOTE you cannot replace this with the variable!
// 'val kotlin_version: String' can't be called in this context by implicit receiver. Use the explicit one if necessary
}
dependencies {
implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
}
Comments
This does not update the suggested version numbers via "Project Structure/Suggestions" in AS/IJ
my inline NOTES indicate several issues with this method!
by buildSrc java Module
Definition
object Ktor {
private const val ktorVersion = "2.0.0"
const val core = "io.ktor:ktor-client-core:${ktorVersion}"
const val android = "io.ktor:ktor-client-android:${ktorVersion}"
}
implementation in build.gradle.kts
implementation(Ktor.android)
Comments
This does not update the suggested version numbers via "Project Structure/Suggestions" in AS/IJ, is seemed to
be totally de-coupled, and it is a nightmare to manually find and update the versions manually to the latest!
However: doing it by buildSrc java Module makes it much easier to re-use in other projects
by Gradle Version Catalogs
Definition
libs.versions.toml // in the gradle directory next to wrapper
[versions]
plugin-kotlin = "1.7.10"
ktor = "2.1.0"
[libraries]
plugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "plugin-kotlin" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
[bundles]
plugins = ["plugin-android", "plugin-kotlin", "plugin-kotlin-serialization", "plugin-sqldelight"]
implementation in build.gradle.kts(project)
buildscript {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
dependencies {
classpath(libs.bundles.plugins)
}
}
implementation in build.gradle.kts(shared)
sourceSets {
val commonMain by getting {
dependencies {
implementation(libs.ktor.client.core)
}
}
}
Comments
This is by far the favorite of mine, the reason is clear, it allows SSOT, and it allows grouping/bundling to make
"sets" that is more understandable later on
However!
This does not update the suggested version numbers via "Project Structure/Suggestions" in AS/IJ
it is a nightmare to manually find and update the versions manually to the latest!
Main question
Is there a better way of managing dependency versions?
Is there a way that works inside the IDE AS/IJ suggestions to update the versions correctly at the definition
location?

Suppress warning “Access to field exceeds its access rights” in Groovy

I write a Groovy script and I need to access a field that has a private access modifier. This works fine but generates a warning:
Access to <field_name> exceeds its access rights
I want to supress this warning. What value of #SuppressWarnings annotation do I have to use in order to achieve it?
I've tried #SuppressWarnings("all") and it works fine but I would like to have more granular control over suppressions. I've also tried #SuppressWarnings("AccessingNonPublicFieldOfAnotherObject") but it has no effect.
Below how this warning looks in IntelliJ:
Unfortunately automatic hint doesn't suggest any sensible solution:
If you are talking about IntelliJ warning:
then you can hit Alt+Enter on the offender and choose "Suppress for method" as follows:
after which you will see #SuppressWarnings("GroovyAccessibility") over your test method:
I had this "problem" when I had buildSrc folder in Gradle-project which contained Kotlin code for my Gradle build scripts and it was used in Groovy code.
Seems like it was because I was accessing private variable field and not the getter. Kotlin makes field private by default. I solved this by using #JvmField in Kotlin code which makes the variable field public and does not generate getter for that field.
// groovy in gradle build script
compileOptions {
sourceCompatibility(CompileOptions.javaVersion)
}
// kotlin in buildSrc (this gives the warning)
object CompileOptions {
val javaVersion = JavaVersion.VERSION_11
}
// kotlin in buildSrc (this does not give the warning as field is now public)
object CompileOptions {
#JvmField val javaVersion = JavaVersion.VERSION_11
}

Choosing different libraries for compilation and runtime

I have two libraries with same classes defined in each one. However they have some different contents (methods/constants).
For example:
Library 1:
package com.test.package;
Class A {
// only method signatures
public void methodA() {
}
public void methodB() {
}
}
Library 2:
package com.test.package;
Class A {
public void methodA() {
// some logic that MUST be executed to provide backward compatibility
}
}
My application uses Library 1 and Library 2 and run in devices which have com.test.package.ClassA, but com.test.package.ClassA.methodB() will only exist in newer releases in framework. Said that, I need the Library 1 to be used to compile my application and the Library 2 to execute a different implementation of methodA().
I have tried to do this in Android Studio using .jar and .aar libraries format, but none of them worked for me.
Is it possible to set this configuration in an Android Studio project?
I am building both Library 1 and 2, and I cannot add methodB() in Library 2.
For a simple Java application, you can do this by unlinking the compile and runtime configurations. I set up an example repository here.
The idea is shown in this commit, but can be described as manually resetting the runtime configuration so that it doesn't include the contents of the compile configuration. After doing so, you can just include your runtime library variation in the runtime configuration.
The application's build.gradle becomes something like:
apply plugin: 'application'
mainClassName = 'my.package.MyAppClass'
configurations.runtime.extendsFrom = [] // Reset runtime configuration
dependencies {
compile 'my.group:my.artifact:2.0' // Library 1, with the new method
runtime 'my.group:my.artifact:1.0' // Library 2, without the method
}
For Android, this can be a little more complicated. The problem is that there's no runtime configuration for Android (because you don't execute it on your computer, unless you're using Robolectric or something similar).
I think there are a few workarounds you can probably use, but one initial suggestion would be to create a wrapper library that abstracts away the dependency on the other libraries. This wrapper library you can compile with the newest library version (Library 1, with the new method). You could then include the wrapper library in the Android app while setting it as a non-transitive dependency and including the other library version:
dependencies {
compile 'my.group:my.wrapped.artifact:0.1' {
transitive = false // Don't include dependencies of the wrapper
// i.e., don't include version 2.0 of the lib.
}
compile 'my.group:my.artifact:1.0'
}
This should work because by setting the dependency as non-transitive Gradle doesn't recursively include the dependencies of the wrapper library, so the version used to compile the wrapper isn't included (in theory) in the APK. You can therefore add the old version without causing a conflict.
An example is set up in the same repository, under the Android branch. Firstly, two Java libraries are created. Then an Android library is created to wrap around the compile-time library. An example activity is created to show how using the wrapper library uses the compile-time library. Then, the latest commit shows how the app is configured to use the wrapper library (which compiles with the newest library) but forces the old library to be included instead in the runtime.
Hope this helps =)

Why is the compiler optimizing out the parameters when using Postsharp with an async method

I started using a Web API cache which I add to particular methods by using an aspect [Cache]. Everything worked great. Later on I changed this method to be async, but since then the compiler started throwing following warnings:
The parameter 'region' of method 'GetTree(System.String,
System.String, System.String[])' has been optimized out by the
compiler and will not be available to the aspect. Disable compiler
optimizations to access the parameter.
Here you can see an example of how I am using Postsharp:
[Cache]
public async Task<IEnumerable<Node>> GetTree(
[FromUri] string region,
[FromUri] string language,
[FromUri] string[] networks)
{
...
await ...
}
What do I need to do in order to get rid of the warning?
The C# compiler optimizations remove the parameters from the state machine class if these parameters are not used anywhere inside the async method. This happens regardless of whether you use PostSharp or not. PostSharp shows you the warning to notify that the removed parameters cannot be accessed inside the aspect.
It's recommended to upgrade to the latest build of PostSharp - the newer versions can handle this issue by re-introducing the missing parameters back into the state machine.
If you cannot upgrade, then the workaround is to disable "Optimize code" in the build page of the project properties for release builds (it's disabled for debug builds by default).

gradle object in a gradle build script

Consider the following method invokation containing in the gradle build script:
gradle.taskGraph.whenReady{taskGraph ->
println gradle.toString()
println "Ready"
}
It prints
build 'task_graph'
Ready
I thought we work in the scope of Project object, since gradle should be a property of that Project object. But there is neither property nor even method with such name. Why can we use it in the build script?
I may be wrong but I think your confusion is that there exists a getGradle() method on the Project interface but no such public field named gradle. This is a Groovy feature. In Groovy, getter and setter methods can by referenced as properties. For example:
println project.description // same as project.getDescription()
project.description = 'My java project' // same as project.setDescription('My java project')
I'd highly suggest familiarizing yourself with Groovy by checking out their documentation. You'll see a lot of differing syntax in Gradle examples simply because there are many different ways to accomplish the same thing in Groovy.

Resources