Jetpack Compose and Android Room compatibility - android

I am trying to set up Android Room in my Jetpack Compose project. However, when trying to add...
kapt "androidx.room:room-compiler:2.2.3"
... to the app build.gradle dependencies. My build fails with the error...
e: java.lang.NoSuchMethodError: org.jetbrains.kotlin.codegen.state.GenerationState$Builder.isIrBackend(Z)Lorg/jetbrains/kotlin/codegen/state/GenerationState$Builder;
Any insight as to why this is? Can we use Android Room with Jetpack Compose yet?

I'm pretty sure that we're still in a state where annotation processors (for Room, Retrofit, etc.) and the experimental Kotlin compiler are not getting along. The recommended approach at the moment is to isolate the Compose stuff in a module that is independent of modules that need annotation processors.

This is currently not supported as kapt does not play well with Jetpack Compose. This issue is being tracked here - https://issuetracker.google.com/issues/143232368

It's actually working, but not without some changes.
For a new project created with AndroidStudio 2020.3.1 Canary 2:
In build.gradle (Project):
Downgrade compose_version to 1.0.0-alpha07 and ext.kotlin_version to 1.4.10.
In build.gradle (Module):
Under composeOptions downgrade the composeCompilerVersion to 1.4.10.
Under dependencies change "androidx.compose.ui:ui-tooling:$compose_version" to "androidx.ui:ui-tooling:$compose_version".
In Main activity - change the import for the preview, as it depends on ui-tooling.
Add room dependencies.
Should work.
However, some newer Compose functionalities won't probably work, as they are explicitly stating, that one should use Kotlin version 1.4.20 and above.

Related

Kotlin 1.6, Jetpack Compose 1.1.0 compilation error

I have updated my project to Kotlin 1.6.10, Compose 1.1.0-rc01 and compose compiler to 1.1.0-rc02, because I need some new features in Compose.
During compilation I have now this error, any solution ?
It was working with Kotlin 1.5.31, Compose/Compose compiler 1.0.5
java.lang.IllegalStateException: Symbol for kotlin.collections/mutableMapOf|-4813910536206556932[0] is unbound
at org.jetbrains.kotlin.ir.symbols.impl.IrBindablePublicSymbolBase.getOwner(IrPublicSymbolBase.kt:52)
at org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionPublicSymbolImpl.getOwner(IrPublicSymbolBase.kt:74)
at androidx.compose.compiler.plugins.kotlin.lower.LiveLiteralTransformer.visitCall(LiveLiteralTransformer.kt:663)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:199)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:24)
at org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl.accept(IrCallImpl.kt:47)
at org.jetbrains.kotlin.ir.expressions.IrExpression.transform(IrExpression.kt:33)
at org.jetbrains.kotlin.ir.expressions.IrExpressionBody.transformChildren(IrBody.kt:46)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBody(IrElementTransformerVoid.kt:108)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitExpressionBody(IrElementTransformerVoid.kt:114)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitExpressionBody(IrElementTransformerVoid.kt:115)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitExpressionBody(IrElementTransformerVoid.kt:24)
at org.jetbrains.kotlin.ir.expressions.IrExpressionBody.accept(IrBody.kt:36)
at org.jetbrains.kotlin.ir.expressions.IrExpressionBody.transform(IrBody.kt:39)
at org.jetbrains.kotlin.ir.declarations.IrField.transformChildren(IrField.kt:41)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:57)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitField(IrElementTransformerVoid.kt:81)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitField(IrElementTransformerVoid.kt:82)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitField(IrElementTransformerVoid.kt:24)
at org.jetbrains.kotlin.ir.declarations.IrField.accept(IrField.kt:34)
at org.jetbrains.kotlin.ir.IrElement$DefaultImpls.transform(IrElement.kt:32)
at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:19)
at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
at org.jetbrains.kotlin.ir.declarations.IrClass.transformChildren(IrClass.kt:66)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:57)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:66)
at androidx.compose.compiler.plugins.kotlin.lower.LiveLiteralTransformer.access$visitClass$s780614737(LiveLiteralTransformer.kt:158)
at androidx.compose.compiler.plugins.kotlin.lower.LiveLiteralTransformer$visitClass$1.invoke(LiveLiteralTransformer.kt:466)
at androidx.compose.compiler.plugins.kotlin.lower.LiveLiteralTransformer$visitClass$1.invoke(LiveLiteralTransformer.kt:465)
at androidx.compose.compiler.plugins.kotlin.lower.DurableKeyVisitor.siblings(DurableKeyVisitor.kt:117)
at androidx.compose.compiler.plugins.kotlin.lower.DurableKeyVisitor$siblings$1.invoke(DurableKeyVisitor.kt:131)
at androidx.compose.compiler.plugins.kotlin.lower.DurableKeyVisitor.enter(DurableKeyVisitor.kt:96)
at androidx.compose.compiler.plugins.kotlin.lower.DurableKeyVisitor.siblings(DurableKeyVisitor.kt:131)
at androidx.compose.compiler.plugins.kotlin.lower.LiveLiteralTransformer.siblings(LiveLiteralTransformer.kt:194)
at androidx.compose.compiler.plugins.kotlin.lower.LiveLiteralTransformer.visitClass(LiveLiteralTransformer.kt:465)
etc.....```
I encountered the exact same issue on two different projects when updating the Compose & Kotlin versions.
Removing the kotlin-android-extensions plugin resolved the issue on both projects for me. This means you can no longer use Kotlin synthetics for view binding.
I've seen a few other reports (and myself) seeing the same thing. One temporary workaround is to use new compose with an older compose compiler that doesn't force you to upgrade kotlin since you only need the new compose functionality. Add something like this in your build.gradle with a similar compose version that supports your kotlin version (https://developer.android.com/jetpack/androidx/releases/compose-kotlin)
composeOptions {
kotlinCompilerExtensionVersion = '1.1.0-beta03'
}
This issue arises when you use both Jetpack Compose & kotlin synthetic bindings on the same project.
Removing the kotlin-android-extensions (used for synthetic binding) plugin will resolve the issue.
Also, synthetic binding is now deprecated you should migrate the code to view binding.
https://developer.android.com/topic/libraries/view-binding/migration
But this was not possible for me at this moment which will require at least 5-6 days for me to do so as I have around 50-60 files using this.
So I have to choose the other way around for this case,
composeOptions {
kotlinCompilerExtensionVersion "1.1.0-beta03"
}
I also have to downgrade the Kotlin version for this.
ext.kotlin_version = "1.5.31"
ext.compose_version = '1.1.1'
Upgrading the Kotlin version fixed my problem. While upgrading, please check the Compose-Kotlin compatibility check mentioned in the developer docs
I have upgraded to Kolin : 1.6.20 and used kotlinCompilerExtensionVersion = "1.2.0-alpha08". This is an older Kotlin version, you can try the latest one.
Use below versions to fix the problem
composeOptions {
kotlinCompilerExtensionVersion '1.1.0-beta03'
kotlinCompilerVersion '1.5.31'
}

Why kotlin.collections is not implicitly imported after upgrading to jetpack compose 1.0.0-beta01?

After upgrading to jetpack compose 1.0.0-beta01, I tried to use arrayListOf, listOf from kotlin.collections but they seemed to not implicitly imported.
Your problem is probably related to what Kotlin version you are using.
I guess I went through a similar process as
you did when I was updating to the new version of Jetpack Compose library, where
as a "side effect" I was forced to update kotlin and kotlin-gradle-plugin version what then
indirectly caused your (and mine) problem. Following workaround should fix it.
Most likely you are using Kotlin 1.4.30 after updating Jetpack Compose to 1.0.0-beta01. Update Kotlin to fixed 1.4.31 version and your problem will be ALMOST "resolved".
I think the whole problem is somehow related to the following bug in 1.4.30 if
you are more interested https://youtrack.jetbrains.com/issue/KT-44845
Now after trying to build your project you will get a nice error saying This version (1.0.0-alpha13) of the Compose Compiler requires Kotlin version 1.4.30 but you appear to be using Kotlin version 1.4.31 which is not known to be compatible. Please fix your configuration (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).
suppressKotlinVersionCompatibilityCheck is a compile argument which in my case I have set in module build.gradle file under android -> kotlinOptions this way:
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
useIR = true
//here -->
freeCompilerArgs += ["-P", "plugin:androidx.compose.compiler.plugins.kotlin:suppressKotlinVersionCompatibilityCheck=true"]
}
It also depends on the type of build.gradle files.
Read more about how to set those compile arguments at
Configure compiler arguments
where are described different ways for groovy and also for kotlin based gradle files.
Now you should be fine but bear in mind that you want to get rid of the suppressKotlinVersionCompatibilityCheck argument as soon as there is a new version of Jetpack Compose relying on a newer version of Kotlin.

Getting weird bugs when trying to update to Kotlin 1.4.0. How to make it work with Gradle and IntelliJ IDEA 2020.2.1?

Kotlin 1.4.0 is stable now. Therefor, I wanted to update my multi module Android project to use it. I set IDEA to use Kotlin plugin 1.4.0-release-IJ2020.2-1 and in my buildSrc build.gradle.kts using Kotlin DSL, I'm loading Kotlin for the jvm like this:
plugins {
kotlin("jvm") version "1.4.0"
}
My app level plugins block looks like this
plugins {
id("com.android.application")
id("com.google.gms.google-services")
kotlin("android")
kotlin("kapt")
id("kotlin-android-extensions")
id("androidx.navigation.safeargs.kotlin")
}
I have also added the Kotlin stdlib to my app level build.gradle.kts dependencies
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.0")
When trying to build my project now, I get multiple Errors like the following:
'let((T) -> R): R' is only available since Kotlin 1.3.50 and cannot be used in Kotlin 1.3
I don't understand. How is gradle trying to use Kotlin 1.3 here? Any idea on how to fix this? Its working fine when using Kotlin v1.3.72 instead.
What I tried so far:
Clean Project
Invalidate caches and restart
Delete .gradle folder and restart
Fix broken classes paths
UPDATE
Forgot to mention that I'm also getting the following warning. How is it unsupported when it is stable?
> Configure project :buildSrc
WARNING: Unsupported Kotlin plugin version.
The `embedded-kotlin` and `kotlin-dsl` plugins rely on features of Kotlin `1.3.72` that might work differently than in the requested version `1.4.0`.
Maybe you should add the Kotlin standard lib to your dependencies explicitly?
dependencies {
implementation(kotlin("stdlib"))
}
With Kotlin 1.4 it is no longer required it add this dependency. The plugin applies the Stdlib by default to the projects it is applied to.
From the Kotlin 1.4 release notes:
You no longer need to declare a dependency on the stdlib library in any Kotlin Gradle project, including a multiplatform one. The dependency is added by default.
The automatically added standard library will be the same version of the Kotlin Gradle plugin, since they have the same versioning.

Why must $kotlin_version be explicitly specified in Android?

Supporting Kotlin in an Android studio project requires two dependencies: kotlin-gradle-plugin in Project/build.gradle and kotlin-stdlib-jdk7 in Project/app/build.gradle, and these two need to have the same version. The common method seems to be using a single kotlin_version variable which you then have to manually change when the IDE updates its Kotlin plugin — as of Android Studio 3.1.3, the IDE is still not able to automatically update the dependencies if you use a $variable as the version.
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
In non-Android Kotlin projects i.e. those using apply: 'kotlin' instead of apply plugin: 'kotlin-android', it is possible to simply omit the version from the kotlin-stdlib-jdk7 dependency, which will then be automatically resolved from the plugin.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7'
This even works on non-Android modules within Android projects. My question is, why is this not possible in Android modules? Why can't the $kotlin_version simply be omitted? If the feature has been present since Kotlin 1.1.2, why is it still causing compile errors on Android even on Kotlin 1.2.51? Or is it actually possible to do this, and if so, how can it be done?
In fact this is not Kotlin specific but has to do with how Gradle manages dependencies.
See https://docs.gradle.org/current/userguide/declaring_dependencies.html on how to specify the version of a dependency in Gradle.
In this case
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
is the standard way of setting the version. As the this version number is the same for several dependency it is declared in a variable in order to make it easy to change the version for all Kotlin libraries.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7'
Uses dependency constraints which are available since Gradle 4.6. It is used for the same purpose. One can set the version of a library in a central place and this way keep the version at a common value without having to go through all gradle.properties files of a larger project.

WorkManager: Dependency Issue with Kotlin

I'm getting the following error while trying to use Work Manager. I've migrated my project to AndroidX and all other architecture components are working.
def work_version = "1.0.0-alpha02"
/* Work Manager for Background Tasks */
implementation "android.arch.work:work-runtime:$work_version"
implementation "android.arch.work:work-firebase:$work_version"
I'm quite sure I need some dependencies from the Support Library. But I have no clue which one's they are.
I've tried adding the annotations package since the error says it can't find a class file for RestrictTo$Scope. Still doesn't work.
implementation "com.android.support:support-annotations:28.0.0-alpha1"
You are including a reference to the wrong support library, you want the androidx one.
androidx.annotation
Look in
AndroidX refactoring
you will find
androidx.annotation:annotation:1.0.0-alpha1
to correspond with
com.android.support:support-annotations
Make sure that you have only libraries for one or the other kind in your dependencies (project wide).

Categories

Resources