I'm getting a compilation error that I have described below. I have tried different solution provided on similar question like mine but neither of them worked for me.
Please help me with this.
The errors I'm getting:-
(1)
error: Type of the parameter must be a class annotated with #Entity or a collection/array of it.
kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
(2)
error: Not sure how to handle insert method's return type.
public abstract java.lang.Object addTransaction(#org.jetbrains.annotations.NotNull()
(3)
error: Not sure how to handle delete method's return type. Currently the supported
return types are void, int or Int.
public abstract java.lang.Object deleteTransaction(#org.jetbrains.annotations.NotNull()
(4)
error: Type of the parameter must be a class annotated with #Entity or a
collection/array of it.
kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
(5)
Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction
> java.lang.reflect.InvocationTargetException (no error message)
This is a compilation error that I am getting while building:-
DAO class:
package com.tallileo.myapplication.TransactionDatabase
import androidx.lifecycle.LiveData
import androidx.room.*
#Dao
interface TransactionDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addTransaction(transaction:Transaction)
#Delete
suspend fun deleteTransaction(transaction:Transaction)
#Query("SELECT * FROM transactions ORDER BY id DESC")
fun getAllTransaction():LiveData<List<Transaction>>
}
Entity Class:
package com.tallileo.myapplication.TransactionDatabase
import androidx.room.Entity
import androidx.room.PrimaryKey
#Entity(tableName = "transactions")
data class Transaction(
val transactionType:String,
val amountType:String,
val name:String,
val amount:String,
val accountTo:String,
val accountFrom:String,
val categoryType:String,
val currency:String,
var additionalNote:String=""
) {
#PrimaryKey(autoGenerate = true)
var id:Int=0
}
Database Class:
package com.tallileo.myapplication.TransactionDatabase
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
#Database(entities = [Transaction::class], version = 1, exportSchema = true)
abstract class TransactionDatabase : RoomDatabase() {
abstract fun transactDao():TransactionDao
companion object {
// Singleton prevents multiple instances of database opening at the
// same time.
#Volatile
private var INSTANCE: TransactionDatabase? = null
fun getDatabase(context: Context): TransactionDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
TransactionDatabase::class.java,
"TransactionDatabase"
).build()
INSTANCE = instance
// return instance
instance
}
}
}
}
build.gradle:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.tallileo.myapplication"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {
def roomVersion = "2.3.0"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//Lottie Animation
implementation 'com.airbnb.android:lottie:3.4.0'
//room components
implementation("androidx.room:room-runtime:$roomVersion")
kapt("androidx.room:room-compiler:$roomVersion")
implementation 'androidx.room:room-common:2.3.0'
implementation("androidx.room:room-ktx:$roomVersion")
}
Kotlin version is 1.6.0. Also when I remove suspend from all the methods in the DAO, then there is no compilation error.
All of your room versions should be the same. You have expressly called out common differently than the rest. Why not let common just come in transitivley?
Had the same problem as well, updating my room_version from '2.3.0' to '2.4.0-beta02' fixed it!
Related
I'm new learning Kotlin and I'm developing a Notes app to practise with databases and viewModels.
I'm having trouble generating my database and the app crashes when it should generate the database and shows me this error on the logcat:
"java.lang.RuntimeException: cannot find implementation for com.example.blocnotas.database.AppDatabase. AppDatabase_Impl does not exist"
This is how I made my Database class:
package com.example.blocnotas.database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
#Database(entities = [Notes::class], version = 1, exportSchema = false)
abstract class AppDatabase: RoomDatabase() {
abstract fun noteDao(): NoteDao
companion object {
#Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"app_notes_database")
.build()
INSTANCE = instance
return instance
}
}
}
My Application class:
package com.example.blocnotas
import android.app.Application
import com.example.blocnotas.database.AppDatabase
class NotesApplication : Application() {
val database: AppDatabase by lazy { AppDatabase.getDatabase(this) }
}
My app gradle:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
//id 'androidx.navigation.safeargs.kotlin'
}
android {
namespace 'com.example.blocnotas'
compileSdk 32
defaultConfig {
applicationId "com.example.blocnotas"
minSdk 19
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
}
Does anybody know how can i fix it and generate my database table?
I leave you the gitHub repository where i'm making it so if it can help get any extra necessary information: https://github.com/R3inbow/BlocNotasApp.git
I finally solved it changing in the gradle the "kapt" for "ksp" this way:
In dependencies:
ksp "androidx.room:room-compiler:$room_version"
In plugins:
id 'com.google.devtools.ksp' version '1.7.20-1.0.6'
Yes I have already tried some old guides, I described it below.
I created new project for Room Database in Kotlin Android. I followed the official google documentation for it.
https://developer.android.com/training/data-storage/room
If I follow as per documentation I get error
java.lang.RuntimeException: cannot find implementation for com.example.laptopsdb.AppDatabase. AppDatabase_Impl does not exist
I also tried changing room-runtime to room-ktx but the error is same. Moreover, I tried adding id 'kotlin-kapt' and changing annotationProcessor to kapt but that give me following error, errors actually, bunch of them, while auto opening UserDao.java file
https://github.com/subjectOneThree/StackOverFLowShares/blob/main/Screenshot_20220715_215040.png
My code is almost stock according to documentation, however you can checkout if I made any stupid mistake
build.gradle (app)
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
//id 'kotlin-kapt'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.laptopsdb"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
apply plugin: "kotlin-kapt"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
def room_version = "2.4.2"
//implementation "androidx.room:room-ktx:$room_version"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
//kapt "androidx.room:room-compiler:$room_version"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
User.kt
#Entity (tableName = "laptops")
data class User(
#PrimaryKey val uid: Int,
#ColumnInfo(name = "first_name") val firstName: String?,
#ColumnInfo(name = "last_name") val lastName: String?
)
UserDao.kt
#Dao
interface UserDao {
#Query("SELECT * FROM laptops")
suspend fun getAll(): List<User>
#Query("SELECT * FROM user WHERE uid IN (:userIds)")
suspend fun loadAllByIds(userIds: IntArray): List<User>
#Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
"last_name LIKE :last LIMIT 1")
suspend fun findByName(first: String, last: String): User
#Insert
suspend fun insertAll(vararg users: User)
#Delete
suspend fun delete(user: User)
}
AppDatabase.kt
#Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "laptops"
).build()
val userDao = db.userDao()
GlobalScope.launch(Dispatchers.Default) {
userDao.insertAll(User(2,"Hello","World"))
val users: List<User> = userDao.getAll()
Log.d("Room Activity", users.toString())
}
}
}
Some of the older project, and a project from my friend have exactly the same code (as far as I have looked into it) and they are working fine. But now when I am trying to create new project it is giving me error. I have tried building several projects before posting here.
(comment) doing this:
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "laptops"
).build()
in the onCreate of mainActivity is a very bad way of creating a database instance, unless you want multiple database instances in one app!
solution:
try changing your build.gradle to this:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
apply plugin: 'kotlin-kapt'
android {
compileSdk 32
defaultConfig {
applicationId "com.example.laptopsdb"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
def room_version = "2.4.2"
kapt("androidx.room:room-compiler:2.4.2")
implementation("androidx.room:room-runtime:2.4.2")
implementation("androidx.room:room-ktx:2.4.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
EDIT:
After creating a project with the same code you have I noticed some rather strange bugs:
in your User.kt file you declared the table name of that entity to "laptops", but in your UserDao you still refered to a table named user, which does not exist (???), that's why room had some troubles with your dao
You declare your uid as Primary Key, which SHOULD NEVER be a duplicate, every single one of the keys should differ, yet in your main activity you use "userDao.insertAll(User(2,"Hello","World"))", which will result in a crash on second run, just remove that line
using "GlobalScope.launch(Dispatchers.Default)" to run a coroutine isn't really encouraged, GlobalScope is even marked in the android studio as a delicate API and using it without proper knowledge first may result in strange bugs or even memory leaks, just use a viewModel to handle all of the work
As I also stated before,
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "laptops"
).build()
do not use that to create database instance
update your build.gradle to:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
apply plugin: 'kotlin-kapt'
android {
compileSdk 32
defaultConfig {
applicationId "com.example.laptopsdb"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// you may add the variable, just keep the version correct
implementation "androidx.room:room-runtime:2.5.0-alpha02"
implementation "androidx.room:room-ktx:2.5.0-alpha02"
kapt "androidx.room:room-compiler:2.5.0-alpha02"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
and the dao to:
#Dao
interface UserDao {
#Query("SELECT * FROM laptops")
suspend fun getAll(): List<User>
#Query("SELECT * FROM laptops WHERE uid IN (:userIds)")
suspend fun loadAllByIds(userIds: IntArray): List<User>
#Query("SELECT * FROM laptops WHERE first_name LIKE :first AND " +
"last_name LIKE :last LIMIT 1")
suspend fun findByName(first: String, last: String): User
#Insert
suspend fun insertAll(vararg users: User)
#Delete
suspend fun delete(user: User)
}
What is going on with RoomDB and Kotlin coroutines? I am trying, again and again, to use suspend function in Room Dao but every time it shows an error. I even follow the android codelabs example. But it shows an error again. the app doesn't even build if I write suspend in Dao. But if I remove suspend keyword it builds successfully.
It shows the error below:
error: Type of the parameter must be a class annotated with #Entity or a collection/array of it.
kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
My Entity:
import androidx.room.Entity
import androidx.room.PrimaryKey
#Entity(tableName = "vocabulary")
class Vocabulary(
#PrimaryKey(autoGenerate = true)
val vocabularyId: Long,
val word: String,
val meaning: String,
val definition: String,
val example: String,
val partsOfSpeech: String,
val synonyms: String,
val antonyms: String,
val phonetics: String,
val folderId: Long,
val isLearned: Int
)
My Dao:
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
#Dao
interface VocabuilderDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertVocab(vocabulary: Vocabulary)
}
My Database class:
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
#Database(entities = [Vocabulary::class], version = 1, exportSchema = false)
public abstract class VocabuilderRoomDb : RoomDatabase(){
abstract fun vocabuilderDao(): VocabuilderDao
companion object{
#Volatile
private var INSTANCE: VocabuilderRoomDb? = null
fun getRoomDatabase(context: Context): VocabuilderRoomDb{
return INSTANCE ?: synchronized(this){
val instance = Room.databaseBuilder(
context.applicationContext,
VocabuilderRoomDb::class.java,
"vocabuilder_roomdb"
).build()
INSTANCE = instance
instance
}
}
}
}
My build.gradle (project level):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.6.0'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
ext {
activityVersion = '1.2.3'
appCompatVersion = '1.3.0'
constraintLayoutVersion = '2.0.4'
coreTestingVersion = '2.1.0'
coroutines = '1.5.0'
lifecycleVersion = '2.3.1'
materialVersion = '1.3.0'
roomVersion = '2.3.0'
// testing
junitVersion = '4.13.2'
espressoVersion = '3.1.0'
androidxJunitVersion = '1.1.2'
}
task clean(type: Delete) {
delete rootProject.buildDir
}
My build.gradle(module):
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.domesoft.vocabuilder"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"
// Dependencies for working with Architecture components
// You'll probably have to update the version numbers in build.gradle (Project)
// Room components
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"
// Kotlin components
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
// UI
implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
implementation "com.google.android.material:material:$rootProject.materialVersion"
// Testing
testImplementation "junit:junit:$rootProject.junitVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
}
If you using kotlin version (1.7.0) shoud work with room latest alpha version (2.5.0-alpha02)
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0"
implementation "androidx.room:room-runtime:2.5.0-alpha02"
implementation "androidx.room:room-ktx:2.5.0-alpha02"
kapt "androidx.room:room-compiler:2.5.0-alpha02"
If you want using room in stable version (2.4.2) should work with kotlin version (1.6.20)
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20"
implementation "androidx.room:room-runtime:2.4.2"
implementation "androidx.room:room-ktx:2.4.2"
kapt "androidx.room:room-compiler:2.4.2"
I have tried both and they work. this is the reference: issue tracker
Update the Room version to 2.4.0-rc01.
In my case it solved the problem, and it works with Kotlin 1.6.0.
For me, kotlin-gradle-plugin 1.6.0 didn't work:
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
but 1.5.31 worked:
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31'
Kotlin 1.6.0 with Room 2.4.0-rc01 worked too.
Thanks Stefano.
I'm trying to call the await() function in the
bookList = bookViewModel.getBookList().await()
in the Main Activity but it gives the error in the header.
Main Activity
#AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val bookViewModel: BookViewModel by viewModels()
private var bookList : BookList? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GlobalScope.launch(Dispatchers.IO) {
bookList = bookViewModel.getBookList().await()
}
setContent {
LOTRAppTheme {
}
}
}
}
ViewModel
package com.example.lotrapp
import androidx.lifecycle.ViewModel
import com.example.lotrapp.models.BookList
import com.example.lotrapp.repository.BookRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
#HiltViewModel
class BookViewModel #Inject constructor(
private val repository: BookRepository
) : ViewModel() {
suspend fun getBookList() : BookList? {
return repository.getBookList()
}
}
Repository
package com.example.lotrapp.repository
import com.example.lotrapp.models.BookList
import com.example.lotrapp.network.RetrofitApi
import javax.inject.Inject
class BookRepository #Inject constructor(
private val retrofitApi: RetrofitApi
) {
suspend fun getBookList() : BookList?
{
return retrofitApi.getBookList().body()
}
}
Api
package com.example.lotrapp.network
import com.example.lotrapp.models.BookList
import retrofit2.Response
import retrofit2.http.GET
interface RetrofitApi {
#GET("book")
suspend fun getBookList() : Response<BookList>
}
Gradle:
plugins {
id 'com.android.application'
id 'kotlin-android'
id("dagger.hilt.android.plugin")
id("kotlin-kapt")
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.lotrapp"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.10'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
def compose_version = "1.0.2"
def lifecycle_version = "2.3.1"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$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")
implementation 'androidx.activity:activity-compose:1.3.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//Hilt
implementation("com.google.dagger:hilt-android:2.38.1")
kapt("com.google.dagger:hilt-android-compiler:2.38.1")
//Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2")
}
kapt {
correctErrorTypes true
}
First I want to pull the list from the api and then show it in the UI with a Composable function (with LazyColumn) in setContent. It is enough to solve this error, but if you have better code suggestions, I would appreciate it. Thank you!
It doesn't really seem you need to invoke await() there. getBookList() returns BookList? directly, so just remove await() and it should be fine.
Additionally, you said you need to use this bookList in setContent. In that case you need to move setContent into launch block, below getBookList(). Right now setContent really executes before bookList is acquired. It is hard to provide more details without the full contents of setContent.
I'm making ToDo application with Room Database. I got kaptDebugKotlin build error, so have been find what is cause. Now I find out but there's some problem. I made new project and copied the problem part(Room Database codes) to there. I saw database part's code makes Impl file(ToDoDatabase_Impl.java etc.) automatically in test project and build well, but it doesn't make Impl in my main project and cannot build.
What is Impl file? and under what conditions is the Impl file automatically generated or not?
I changed every annotationProcessor to kapt.
My code is below.
ToDoDao.kt
package com.overeasy.hiptodo.model
import androidx.room.*
#Dao
interface ToDoDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(toDo: ToDo)
#Update(onConflict = OnConflictStrategy.REPLACE)
suspend fun update(toDo: ToDo)
#Delete
suspend fun delete(toDo: ToDo)
}
ToDoDatabase.kt
package com.overeasy.hiptodo.model
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
#Database(
entities = [ToDo::class],
version = 1
)
abstract class ToDoDatabase : RoomDatabase() {
abstract fun toDoDao(): ToDoDao
companion object {
#Volatile
private var INSTANCE: ToDoDatabase? = null
fun getInstance(context: Context) : ToDoDatabase? {
if (INSTANCE == null) {
synchronized(this) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
ToDoDatabase::class.java,
"todo_database"
).build()
}
}
return INSTANCE
}
}
}
ToDo.kt
package com.overeasy.hiptodo.model
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
#Entity
class ToDo {
#PrimaryKey(autoGenerate = true)
var id: Int? = null
var something: String
var date: Long?
#Ignore
var day: Long? = null
constructor(something: String) {
this.something = something
this.date = null
}
constructor(something: String, date: Long) {
this.something = something
this.date = date
}
}
build.gradle (:app)
plugins {
id "com.android.application"
id "kotlin-android"
id "kotlin-kapt"
}
repositories {
jcenter()
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "com.overeasy.hiptodo"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled = true
vectorDrawables.useSupportLibrary = true
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation":"$projectDir/schemas".toString(),
"room.incremental":"true",
"room.expandProjection":"true"]
}
}
}
buildFeatures {
dataBinding true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
def roomVersion = "2.2.5"
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.20"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.20"
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "com.google.android.material:material:1.2.1"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
implementation "io.reactivex.rxjava2:rxkotlin:2.4.0"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0"
implementation "com.jakewharton.rxbinding4:rxbinding-recyclerview:4.0.0"
implementation "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0"
implementation "io.sentry:sentry-android:3.1.0"
implementation "androidx.room:room-ktx:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"
testImplementation "junit:junit:4.13.1"
androidTestImplementation "androidx.test.ext:junit:1.1.2"
androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0"
}
This is terrible. I've been spent almost 2 weeks to solve this problem. But still can't.
When you do toDoDao.insert(someToDo), you must ask yourself, how is this code working? abstact interface functions can't be called, then where is the implementation of insert(ToDo) function?
Implementation of all the functions defined in the #Dao interface is in the YourDao_impl (impl is short for implementation, implementation of your #Dao interface) which is automatically generated by the room annotation processor.
To appreciate the use of _impl class you must understand that When reading or writing to SQL databases, there are multiple steps that needs to be performed almost always. in most cases these steps would look as following:
1. Connect to database (In case of android, need to use SQLiteOpenHelper)
2. prepare the query to be executed
3. execute query and receive result
4. build a model from received result (In your case ToDo)
But when using room you only define an interface with #Dao annotation containing abstract functions marked with certain annotations (#Insert, #Update, #Query etc.). what room does is that it automatically generates(using annotation processor) the above listed common steps for all your functions.
I solve this sh×tshow!!! This god-damned error was made by Entity's multiple constructor. Room accept only one constructor. If someone want 2 or more constructor in Entity class, use #Ignore annotation above sub-constructor.
P.S. I got KaptDebugError and _Impl does not exist error. If someone got them although put right dependency in build.gradle or did copy and paste exactly, check your Entity's constructor. It's not the veritas, but can be a solution to someone.