I am stuck with this issue since couple of days. I have gone through many threads where people faced similar issues but did not find any work around on this. Im getting the error because of using suspend in dao interface but when i remove the error goes away but the app crashes when i try to open it after installation. I have tried changing the version of room in gradle but that didnot work either. have a look at my code. The error message
kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
NotesDao.kt
package com.example.notes
import androidx.lifecycle.LiveData
import androidx.room.*
@Dao
interface NoteDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(note : Note)
@Delete
suspend fun delete(note : Note)
@Query("Select * from notes_table order by id ASC")
fun getAllNotes() : LiveData <List<Note>>
}
NotesRCAdapter.kt
package com.example.notes
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class NotesRVAdapter(private val context: Context, private val listner : INotesRVAdapter)
: RecyclerView.Adapter<NotesRVAdapter.NoteViewHolder>() {
val allNotes = arrayListOf<Note>()
class NoteViewHolder (itemview : View) : RecyclerView.ViewHolder(itemview){
val textView = itemView.findViewById<TextView>(R.id.tvNote)
val deleteButton = itemview.findViewById<ImageView>(R.id.ivDelete)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder {
val viewHolder = NoteViewHolder( LayoutInflater.from(context)
.inflate(R.layout.item_note, parent, false))
viewHolder.deleteButton.setOnClickListener{
listner.onItemClicked(allNotes[viewHolder.adapterPosition])
}
return viewHolder
}
override fun onBindViewHolder(holder: NoteViewHolder, position: Int) {
val currentNote = allNotes[position]
holder.textView.text = currentNote.text
}
override fun getItemCount(): Int {
return allNotes.size
}
fun updateList(newList : List<Note>){
allNotes.clear()
allNotes.addAll(newList)
notifyDataSetChanged()
}
}
interface INotesRVAdapter{
fun onItemClicked(note: Note)
}
NotesDataBase.kt
package com.example.notes
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDataBase: RoomDatabase() {
abstract fun getNoteDao(): NoteDao
companion object {
// Singleton prevents multiple instances of database opening at the
// same time.
@Volatile
private var INSTANCE: NoteDataBase? = null
fun getDatabase(context: Context): NoteDataBase {
// 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,
NoteDataBase::class.java,
"note_database"
).build()
INSTANCE = instance
// return instance
instance
}
}
}
}
//after this we will create our repository
NotesRepository.kt
package com.example.notes
import androidx.lifecycle.LiveData
class NoteRepository(private val noteDao: NoteDao) {
val allNotes : LiveData<List<Note>> = noteDao.getAllNotes()
suspend fun insert(note: Note) {
noteDao.insert(note)
}
suspend fun delete(note: Note){
noteDao.delete(note)
}
}
NoteViewModel.kt
package com.example.notes
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 NoteViewModel(application: Application) : AndroidViewModel(application){
private val repository : NoteRepository
val allNotes : LiveData<List<Note>>
init {
val dao = NoteDataBase.getDatabase(application).getNoteDao()
repository = NoteRepository(dao)
allNotes = repository.allNotes
}
fun deleteNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.delete(note)
}
fun insertNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.insert(note)
}
}
Note.kt
package com.example.notes
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "notes_table") /
class Note(@ColumnInfo(name = "text")val text: String) {
@PrimaryKey(autoGenerate = true) var id = 0
}
MainActivity.kt
package com.example.notes
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity(), INotesRVAdapter {
lateinit var viewModel: NoteViewModel
private val input = findViewById<EditText>(R.id.etInput)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val RecyclerView = findViewById<RecyclerView>(R.id.recyclerView)
RecyclerView.layoutManager = LinearLayoutManager(this)
val adapter = NotesRVAdapter(this, this)
RecyclerView.adapter = adapter
viewModel = ViewModelProvider(this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application))
.get(NoteViewModel::class.java)
viewModel.allNotes.observe(this, Observer { list ->
list?.let {
adapter.updateList(it)
}
})
}
override fun onItemClicked(note: Note) {
viewModel.deleteNote(note)
Toast.makeText(this,"${note.text} Deleted", Toast.LENGTH_LONG).show()
}
fun submitData(view: View) {
val noteText = input.text.toString()
if (noteText.isNotEmpty()){
viewModel.insertNote(Note(noteText))
Toast.makeText(this,"$noteText Inserted", Toast.LENGTH_LONG).show()
}
}
}
immediate help will be appreciated in understanding the issue and where I went wrong. Thanks.