Android Room in Kotlin 1.7.0 - android

When updating to Kotlin 1.7.0, since it's required by the latest version of Jetpack Compose, I found out that Room was no longer working. I was using kapt as my annotation processor, and the compiler was throwing error messages such as:
[*] error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this.

The fix was to migrate from kapt to ksp. KSP is the theoretical successor of kapt, and it's developed by Google. To do so, first I had to import the library into my classpath:
buildscript {
...
repositories {
...
classpath "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:1.7.0-1.0.6"
...
}
}
Check the latest version from MVN Repository just in case there has been an update, but as the time of writing this the latest version for Kotlin 1.7.0 is 1.7.0-1.0.6.
Now, in my module's build.gradle:
plugins {
...
// Remove the old kapt plugin
id 'org.jetbrains.kotlin.kapt'
// Add the new KSP plugin
id 'com.google.devtools.ksp'
...
}
...
android {
...
defaultConfig {
...
// Replace old compile options
javaCompileOptions {
annotationProcessorOptions {
arguments += [ "room.schemaLocation": "$projectDir/schemas".toString() ]
}
}
// With the new KSP arg method
ksp {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
...
}
...
}
...
dependencies {
...
// Replace all kapt calls with ksp
// kapt "androidx.room:room-compiler:$room_version"
ksp "androidx.room:room-compiler:$room_version"
}
Now Room should be working correctly in Kotlin 1.7.0!

You can update the room version to 2.5.0-alpha02, which supports Kotlin 1.7.0, but it's still in alpha. Check the latest release here

Upgrading Room to stable version 2.4.3 has fixed this issue (for me) - I can now build the project with Kotlin 1.7.10.

Related

Failed to resolve: androidx.compose ... 1.4.0

As per latest https://developer.android.com/jetpack/androidx/releases/compose-kotlin
I can see that we can use
Compose Compiler Version - 1.4.0
Compatible Kotlin Version - 1.8.0
However, after upgrade to compose 1.4.0 and kotlin 1.8.0, I got the error below
I got this error
Failed to resolve: androidx.compose.ui:ui-tooling:1.4.0
Failed to resolve: androidx.compose.ui:ui-test-manifest:1.4.0
Failed to resolve: androidx.compose.ui:ui:1.4.0
Failed to resolve: androidx.compose.ui:ui-tooling-preview:1.4.0
Failed to resolve: androidx.compose.ui:ui-test-junit4:1.4.0
Did I miss anything?
Yes, the libraries from the androidx.compose.ui package for compose version 1.4.0 have not been released yet.
The latest version for each of these libs is 1.4.0-alpha04. You can check the versions on this page
Compose compiler and the other compose dependencies have different releases.
Currently only compose.compiler has 1.4.0 stable.
To avoid this kind of problem you have different option:
Use the BOM
The Compose Bill of Materials (BOM) lets you manage all of your Compose library versions by specifying only the BOM’s version. The BOM itself has links to the stable versions of the different Compose libraries, in such a way that they work well together.
Going forward, Compose libraries will be versioned independently, which means version numbers will start to be incremented at their own pace.
Here you can find more info about BOM.
buildscript {
ext {
compose_compiler = '1.4.0' //compiler
}
//...
}
composeOptions {
kotlinCompilerExtensionVersion compose_compiler
}
dependencies {
// Import the Compose BOM
implementation platform('androidx.compose:compose-bom:2022.12.00')
//....
}
Or use different version in your build script:
buildscript {
ext {
compose_compiler = '1.4.0' //compiler
compose_version = '1.3.x' //compose dependencies
compose_material3 = '1.0.1' //material3 release
}
//...
}
and then:
composeOptions {
kotlinCompilerExtensionVersion compose_compiler
}
dependencies {
// compose releases (1.3.x)
implementation "androidx.compose.material:material:$compose_version"
//...
//material3
implementation "androidx.compose.material3:material3:$compose_material3"
}
Apparently, the compose version and composeCompiler version are different.
For now, the compose version is at 1.4.0-alpha04
buildscript {
ext {
compose_ui_version = '1.4.0-alpha04'
}
}
While the composeCompiler is now 1.4.0
android {
...
composeOptions {
kotlinCompilerExtensionVersion '1.4.0'
}
}

Upgrading compose/gradle

I copied project from GitHub and I want to modify it.
But I can't add LazyHorizontalGrid so I guess I need to update Jetpack Compose version or Gradle right?
What is proper way of doing that because if I do it with Project Structure as IDE suggest app crashes and I can't even build project.
I googled error and then next one and then next one and so on. But I think that it shouldn't be so hard to just update project.
LazyHorizontalGrid was added with 1.2.0 of the Compose Foundation dependency.
To update just change your build.gradle files.
In the root build.gradle file:
buildscript {
ext {
compose_version = '1.2.1'
}
//..
dependencies {
//...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
}
}
In your app/build.gradle:
android {
compileSdk 33
//...
composeOptions {
kotlinCompilerExtensionVersion 1.3.1
}
}
dependencies {
implementation "androidx.compose.foundation:foundation:$compose_version"
//...all the other compose dependencies
}
Check also the compatibility map for Compose Compiler Version/Kotlin Version.

Can you use Hilt in a Java-only Android project?

According to the official integration guide, you need to add
plugins {
id 'kotlin-kapt'
...
}
and
dependencies {
implementation "com.google.dagger:hilt-android:{hilt_version}"
kapt "com.google.dagger:hilt-compiler:{hilt_version}"
}
to your build.grade file. However, when I do a gralde sync, I get the following error:
Plugin [id: 'kotlin-kapt'] was not found in any of the following
sources:
is it possible to use Dagger-Hilt in a pure java project? Or do you have to either use plain Dagger or use Kotlin?
Yes, you can use the following instead of kotlin-kapt:
dependencies {
implementation "com.google.dagger:hilt-android:{hilt_version}"
annotationProcessor 'com.google.dagger:hilt-compiler:{hilt_version}'
}
plugins {
id 'dagger.hilt.android.plugin'
}

Android Hilt won't work with plugins added

I have questions about android hilt.
I have added hilt plugin.
//build.gradle(:project)
buildscript {
ext.hilt_version = '2.37'
dependencies {
...
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
}
}
//build.gradle(:app)
plugins {
...
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
dependencies {
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"
}
//MyApplication.kt
#HiltAndroidApp
class MyApplication : Application() {...}
When I build the project,
I get the error message saying
"Expected #HiltAndroidApp to have a value. Did you forget to apply the Gradle Plugin?"
Do you have any idea?
I am also having same problem in my new projects. This error had gone after lowering kotlin version to 1.5.10. I think hilt has compatibility issues with latest kotlin plugin.
As mentioned by others, Kotlin 1.5.20 has a bug in Kapt which causes this issue.
It is fixed in 1.5.21. Just increase the version and you're good.
There is a bug in 1.5.20
To avoid this bug there is a workaround.
in build.gradle (app) file paste this code below.
generally, in the hilt Gradle plugin, these options are set automatically. in 1.5.20 it is not. if you set it manually it will resolve the issue.
kapt {
javacOptions {
option("-Adagger.fastInit=ENABLED")
option("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
}}

How to get rid of Incremental annotation processing requested warning?

I have just started using android development and trying to use Room library. Since yesterday I am facing this warning message
w: [kapt] Incremental annotation processing requested, but support is
disabled because the following processors are not incremental:
androidx.lifecycle.LifecycleProcessor (NON_INCREMENTAL),
androidx.room.RoomProcessor (NON_INCREMENTAL).
I have tried to research and fix but unable to avoid this error here is my grale.build file. please suggest/advice what I am doing wrong.
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "ps.room.bookkeeper"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":"$projectDir/schemas".toString()]
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// life cycle dependencies
def lifecycle_version = "2.0.0"
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
kapt "android.arch.lifecycle:compiler:$lifecycle_version"
//Room dependencies
//def room_version = "2.1.0"
implementation 'android.arch.persistence.room:runtime:2.1.0'
kapt 'android.arch.persistence.room:compiler:2.1.0'
//annotationProcessor 'android.arch.persistence.room:compiler:2.1.0'
// implementation "android.arch.lifecycle:extensions:$room_version"
// kapt "android.arch.persistence.room:compiler:$room_version"
// androidTestImplementation "android.arch.persistence.room:testing:$room_version"
//implementation 'androidx.room:room-runtime:2.1.0'
//annotationProcessor 'androidx.room:room-compiler:2.1.0'
}
Just add this line to you gradle.properties:
kapt.incremental.apt=true
The real problem is that incremental processing makes things faster, but if any of the annotation processors are non incremental, none of them will be actually processed in that way.
What's the purpose of incremental processing?
From version 1.3.30+, incremental processing allowed modules not to be entirely processed again each time a change occurs, giving the build process a better performance:
The main areas of focus for this release have been around
Kotlin/Native, KAPT performance, as well as improvements for IntelliJ
IDEA.
From Kotlin documentation:
Annotation processors (see JSR 269) are supported in Kotlin with the
kapt compiler plugin. In a nutshell, you can use libraries such as
Dagger or Data Binding in your Kotlin projects.
How to fix Room Incremental Processing?
Room incremental annotation processor is disabled by default. This is a known issue and it's described here. They intend to fix it on version 2.2.0. You can just wait for the update or you can enable that to get rid of the warning by setting:
in gradle.properties file:
kapt.incremental.apt=true
(optional steps)
to allow databinding to be incremental:
android.databinding.incremental=true
for faster builds:
kapt.use.worker.api=true
if only a few changes are made, the build time greatly decreases:
kapt.include.compile.classpath=false
(back to the subject)
in your project build.gradle, add the necessary dependencies (Groovy):
dependencies {
...
implementation "androidx.room:room-runtime:2.2.0-rc01"
annotationProcessor "androidx.room:room-compiler:2.2.0-rc01"
}
and
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.incremental":"true"]
}
}
}
}
Kotlin DSL version:
dependencies {
...
implementation("androidx.room:room-runtime:2.2.0-rc01")
kapt("androidx.room:room-compiler:2.2.0-rc01")
}
and
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = mapOf("room.incremental" to "true")
}
}
}
}
October 9, 2019
androidx.room:room-*:2.2.0 is released.
Gradle Incremental Annotation Processor: Room is now a Gradle
isolating annotation processor and incrementability can be enabled via
the processor option room.incremental.
Latest update:
For the newest Kotlin DSL versions, please use
javaCompileOptions {
annotationProcessorOptions {
arguments["room.incremental"] = "true"
}
}
There is a bug in kotlin-gradle-plugin version of 1.3.50 as #Necrontyr mentioned. Just downgrade the kotlin_version in build.gradle(Project) to 1.3.41.
From Room documentation:
"Room has the following annotation processor options...room.incremental: Enables Gradle incremental annotation proccesor."
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation":"$projectDir/schemas".toString(),
"room.incremental":"true",
"room.expandProjection":"true"]
}
}
}
}
Be sure to update the room version to 2.2.x or higher.
Enable Kapt Incremental annotation processing requeste
Use Kotlin 1.3.31 or newer Kotlin 1.3.30 released
In your android kotlin project gradle.properties file
# Enable Kapt Incremental annotation processing requeste
kapt.incremental.apt=true
# Enable android.databinding.annotationprocessor.ProcessDataBinding (DYNAMIC)
android.databinding.incremental=true
# Decrease gradle builds time
kapt.use.worker.api=true
# turn off AP discovery in compile path, and therefore turn on Compile Avoidance
kapt.include.compile.classpath=false
# Enable In Logcat to determine Kapt
kapt.verbose=true
Here is a list of things you can do to fix this and significantly decrease your build times while you're at it.
In your build.gradle (module) file:
android {
...
defaultConfig {
...
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
arg("room.incremental", "true")
arg("room.expandProjection", "true")
}
}
}
...
}
In your gradle.properties file:
kapt.incremental.apt=true // enabled by default on 1.3.50+
kapt.use.worker.api=true // faster builds
kapt.include.compile.classpath=false // near instant builds when there are few changes
android.databinding.incremental=true
android.lifecycleProcessor.incremental=true
//add your specific library if it supports incremental kapt
A lot of the other answers here cover up the error or disable incremental processing instead of actually making it work the way you want.
You can enable incremental processing for your specific library in the gradle.properties file. Just add these settings, or whichever one matches the library that throws the error:
android.databinding.incremental=true
android.lifecycleProcessor.incremental=true
If it's complaining that "Incremental annotation processing requested, but support is disabled because the following processors are not incremental", then setting "kapt.incremental.apt" to "true" (mentioned in a different answer) in gradle.properties is counter-intuitive. You need to set it to "false". That did it for me.
What you really should do is to implement these lines of code in your buildConfig tag in your build.gradle, module app:
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation" : "$projectDir/schemas".toString(),
"room.incremental" : "true",
"room.expandProjection": "true"]
}
}
I'm using AndroidX, but It guess it's the same for android.arch.lifecycle. For me it simply helped replacing this:
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
... with this:
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
So if you're using android.arch.lifecycle it might have the same effect replacing this:
kapt "android.arch.lifecycle:compiler:$lifecycle_version"
... with this:
implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
Be aware that this only works if you're using Java 8 and that you also should remove OnLifecycleEvent annotations for LifecycleObserver classes and let those observers implement DefaultLifecycleObserver instead.
Changing to this method is also recommended in the build.gradle depencies shown here.
Above answers can be useful, but what helped me is reducing the kotlin_version in build.gradle(Project) to 1.3.41 and building the project. This will allow you to see if there is any issue with your entity model.
Mine was, I forgot to annotate #PrimaryKey. Your may be something different. Kotlin 1.3.41 allows to to see those issues. Fix those issues and revert back your kotlin_version to the previous one.
Starting from version 1.3.30, kapt supports incremental annotation processing as an experimental feature. Yet, starting from version 1.3.50, incremental annotation processing is enabled by default.
So, you must add kapt.incremental.apt=true line to your gradle.properties file to enable incremental annotation processing if your kapt version is greater than or equal to 1.3.30 and lower than 1.3.50. Otherwise; you don't have to set kapt.incremental.apt to true to enable it. Although, you can set it to false to disable it if you like.
Besides all of that; incremental annotation processing requires incremental compilation to be enabled as well. So, you must add kotlin.incremental=true line to your gradle.properties file to be able to benefit from incremental annotation processing feature.
Note that incremental annotation processing option of Room is ON by default starting from version 2.3.0-alpha02. It means you don't have to set room.incremental argument to true if your version of the library is greater than or equal to this. To learn more, see issue #112110217.
Also note that if you're using Android Gradle Plugin 3.6.x or newer, incremental annotation processing option is ON by default for Data Binding. So, you don't have to add android.databinding.incremental=true line to your gradle.properties file. To learn more, see issue #110061530.
This can also be caused by character problems such as "İ" on the databinding side when the system language is a non-English language. In such a case, using the computer system language in English will solve the problem.
for me this is happen when my entity with primay key and #NonNull annotation, but type field still using nullable (?). so, just remove this ?, the problem is gone
data class TvEntity(
#PrimaryKey
#NonNull
#ColumnInfo(name = "tvId")
var tvId: String?,

Categories

Resources