Home > Back-end >  Room database not working-2 Errors See Description
Room database not working-2 Errors See Description

Time:07-01

When the app is ran, the following errors occur:

Errors: C:\Users\John\AndroidStudioProjects\Todoit 2\app\build\tmp\kapt3\stubs\debug\com\example\todoit\data\TodoDao.java:11: error: Not sure how to handle insert method's return type. public abstract java.lang.Object addTodo(@org.jetbrains.annotations.NotNull()

C:\Users\John\AndroidStudioProjects\Todoit 2\app\build\tmp\kapt3\stubs\debug\com\example\todoit\data\TodoDao.java:13: 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);

Any help would be greatly appreciated.

Code:

Todo

package com.example.todoit.data

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "todo_data")
data class Todo (
    @PrimaryKey val id: Int,
    val title: String,
    var isChecked: Boolean = false
)

TodoDao

package com.example.todoit.data

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query

@Dao
interface TodoDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun addTodo(todo: Todo)

    @Query("SELECT * FROM todo_data ORDER BY id ASC")
    fun readAllData(): LiveData<List<Todo>>
}

TodoDataBase

package com.example.todoit.data

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(entities = [Todo::class],version = 1, exportSchema = false)
abstract class TodoDataBase: RoomDatabase() {

    abstract fun todoDao(): TodoDao

    companion object{
        @Volatile
        private var INSTANCE: TodoDataBase? = null

        fun getDataBase(context: Context):TodoDataBase{
            val tempInstance = INSTANCE
            if(tempInstance != null){
                return tempInstance
            }
            synchronized(this){
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    TodoDataBase::class.java,
                    "todo_database"
                ).build()
                INSTANCE = instance
                return instance
            }
        }


    }
}

TodoRepository

package com.example.todoit.data

import androidx.lifecycle.LiveData

class TodoRepository(private val todoDao:TodoDao) {
    val readAllData: LiveData<List<Todo>> = todoDao.readAllData()

    suspend fun addTodo(todo:Todo) {
        todoDao.addTodo(todo)
    }
}

TodoViewModel


package com.example.todoit.data

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch




class TodoViewModel(application: Application) : AndroidViewModel(application) {

    private val readAllData: LiveData<List<Todo>>
    private val repository: TodoRepository




    init {
        val todoDao = TodoDataBase.getDataBase(application).todoDao()
        repository = TodoRepository(todoDao)
        readAllData = repository.readAllData
    }


    fun addTodoToDataBase(todo: Todo) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.addTodo(todo)
        }
    }
}

MainActivity

package com.example.todoit

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.todoit.data.Todo
import com.example.todoit.data.TodoViewModel
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {
    private lateinit var todoAdapter: TodoAdapter
    private lateinit var todoViewModel: TodoViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        todoViewModel = ViewModelProvider(this).get(TodoViewModel::class.java)
        todoAdapter = TodoAdapter(mutableListOf())
        rvTodoItems.layoutManager = LinearLayoutManager(this)
        rvTodoItems.adapter = todoAdapter

        btnAddTodo.setOnClickListener {
            val todoTitle = etTodoTitle.text.toString()
            if (todoTitle.isNotEmpty()) {
                val todo = Todo(0,todoTitle,false)
                etTodoTitle.text.clear()
                insertDataToDataBase(todo)
                todoAdapter.addTodo(todo)
        }
        btnDeleteTodo.setOnClickListener {
            todoAdapter.deleteDoneTodos()
        }
    }}

    private fun insertDataToDataBase(todo: Todo) {
        val todoTitle = etTodoTitle.text.toString()

        if(todoTitle.isNotEmpty()) {
            //Add data to database
            todoViewModel.addTodoToDataBase(todo)
        }
    }
}

TodoAdapter

package com.example.todoit

import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.todoit.data.Todo
import kotlinx.android.synthetic.main.item_todo.view.*

class TodoAdapter(
    private val todos: MutableList<Todo>,
    ) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {

    class TodoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
        return TodoViewHolder(
            LayoutInflater.from(parent.context).inflate(
                R.layout.item_todo,
                parent,
                false
            )
        )
    }

    fun addTodo(todo: Todo) {
        todos.add(todo)
        notifyItemInserted(todos.size - 1)
    }

    fun deleteDoneTodos() {
        todos.removeAll { todo ->
            todo.isChecked
        }
        notifyDataSetChanged()
    }

    private fun toggleStrikeThrough(tvTodoTitle: TextView, isChecked: Boolean) {
        if (isChecked) {
            tvTodoTitle.paintFlags = tvTodoTitle.paintFlags or STRIKE_THRU_TEXT_FLAG
        } else {
            tvTodoTitle.paintFlags = tvTodoTitle.paintFlags and STRIKE_THRU_TEXT_FLAG.inv()
        }
    }

    override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
        val curTodo = todos[position]
        holder.itemView.apply {
            tvTodoTitle.text = curTodo.title
            cbDone.isChecked = curTodo.isChecked
            toggleStrikeThrough(tvTodoTitle, curTodo.isChecked)
            cbDone.setOnCheckedChangeListener { _, isChecked ->
                toggleStrikeThrough(tvTodoTitle, isChecked)
                curTodo.isChecked = !curTodo.isChecked
            }
        }
    }

    override fun getItemCount(): Int {
        return todos.size
    }
}

Gradle(Module)

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id "kotlin-android-extensions"
}
apply plugin: 'kotlin-kapt'

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.todoit"
        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 {
    //ROOM
    def roomVersion = "2.4.2"
    implementation 'androidx.room:room-ktx:2.2.1'
    kapt "androidx.room:room-compiler:2.2.1"

    // Navigation Component
    implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
    implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'


    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.6.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    // Lifecycle components
    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
    implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"

    // Kotlin components
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5"
}

Gradle(Project)

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '7.2.0' apply false
    id 'com.android.library' version '7.2.0' apply false
    id 'org.jetbrains.kotlin.android' version '1.5.30' apply false
}



task clean(type: Delete) {
    delete rootProject.buildDir
}

CodePudding user response:

I think you should set the dependencies for room as follows:

def roomVersion = "2.4.2"
implementation "androidx.room:room-ktx:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"

CodePudding user response:

I think... You just missed @ColumnInfo(name = "title") & @ColumnInfo(name = "isChecked").

package com.example.todoit.data

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "todo_data")
data class Todo (
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "title")
    val title: String,
    @ColumnInfo(name = "isChecked")
    var isChecked: Boolean = false
)

Just try this!, And also Keep this mind room database saved their boolean value as a integer value. So fastly change this ;)

@ColumnInfo(name = "isChecked")
var isChecked: Int = 0
  • Related