How to get LiveData from Room? - android

I'm trying to get LiveData from Room. So my RecycleView can have Live updates if anything in database is changed
I have tried with out LiveData and that works, but when i add LiveData that always shows this error.
error: Not sure how to convert a Cursor to this method's return type (androidx.lifecycle.LiveData<java.util.List<com.example.models.Club>>).
public abstract java.lang.Object getAll(#org.jetbrains.annotations.NotNull()
I googled and looked on this site for solution, but every on with this issue have used rxjava, rxandroid, rxkotlin or ArrayList.
And for them solution is to replace ArrayList with List, and for RX to try coroutine.
Well i am using Coroutine and List and still no progress.
This is my ClubDao
ClubDao
#Query("SELECT * FROM club")
suspend fun getAll(): LiveData<List<Club>>
In Club i have this attributes
Club
#Entity
data class Club(#PrimaryKey var id: Int,
#ColumnInfo(name = "logo_url") var logoUrl: String,
#ColumnInfo(name = "name") var name: String,
#ColumnInfo(name = "town") var town: String,
#ColumnInfo(name = "address") var address: String,
#ColumnInfo(name = "contact_name") var contactName: String,
#ColumnInfo(name = "phone_numbers") var phoneNumbers: String,
#ColumnInfo(name = "email") var email: String)
phoneNumbers should be List, but i convert those to and from json with TypeConverters
TypeConverter is here
TypeConverter
class ConvertersDB {
#TypeConverter
fun fromString(value: String): ArrayList<String> {
val listType = object : TypeToken<ArrayList<String>>() {
}.type
return Gson().fromJson(value, listType)
}
#TypeConverter
fun fromArrayList(list: ArrayList<String>): String {
val gson = Gson()
return gson.toJson(list)
}
}
And my DB
DataBase
#Database(entities = [Club::class], version = 1, exportSchema = false)
#TypeConverters(ConvertersDB::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun clubDao(): ClubDao
companion object {
#Volatile
private var instance: AppDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context) = instance ?: synchronized(LOCK) {
instance ?: buildDatabase(context).also { instance = it }
}
private fun buildDatabase(context: Context) = Room.databaseBuilder(context,
AppDatabase::class.java, "pss.db")
.allowMainThreadQueries()
.build()
}
}
In my fragment i need to observe all the clubs from database via ViewModel and Repository and send them to RecycleView
Now i am getting error:
error: Not sure how to convert a Cursor to this method's return type (androidx.lifecycle.LiveData<java.util.List<com.example.models.Club>>).
public abstract java.lang.Object getAll(#org.jetbrains.annotations.NotNull()
Does anyone know solution for this?
EDIT:
Gradle
apply plugin: 'com.android.application'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.overswayit.plesnisavezsrbije"
minSdkVersion 24
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dataBinding {
enabled true
}
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31"
implementation 'com.jakewharton:butterknife:10.1.0'
implementation 'com.google.android.material:material:1.1.0-alpha07'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
// Room components
implementation "androidx.room:room-runtime:$rootProject.roomVersion"
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
// Room and RxJava
implementation "androidx.room:room-rxjava2:$rootProject.roomVersion"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.archLifecycleVersion"
kapt "androidx.lifecycle:lifecycle-compiler:$rootProject.archLifecycleVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.androidxArchVersion"
// ViewModel Kotlin support
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.archLifecycleVersion"
//LiveData Kotlin
implementation "androidx.lifecycle:lifecycle-livedata:$rootProject.archLifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.archLifecycleVersion"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$rootProject.archLifecycleVersion"
// Coroutines
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
//RxJava
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "io.reactivex.rxjava2:rxjava:2.2.6"
implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2'
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.31"
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.kaopiz:kprogresshud:1.0.5'
implementation 'com.squareup:otto:1.3.8'
implementation 'agency.tango.android:avatar-view:0.0.2'
implementation 'agency.tango.android:avatar-view-picasso:0.0.2'
implementation 'com.mikhaellopez:circularimageview:3.2.0'
implementation 'com.googlecode.libphonenumber:libphonenumber:8.1.0'
// Data Binding
kapt "com.android.databinding:compiler:3.1.4"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation project(path: ':tuple')
// Navigation Component
implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
//Gson
implementation 'com.google.code.gson:gson:2.8.5'
}
kapt {
generateStubs = true
}
Top Level Gradle
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.31"
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext {
roomVersion = '2.1.0'
archLifecycleVersion = '2.2.0-alpha01'
androidxArchVersion = '2.0.0'
coroutines = '1.2.0'
}

As mentioned in the comments, remove suspend.
When a method returns an observable, there is no reason to make it suspend since it just returns and object, does not run any query until it is observed.
#Query("SELECT * FROM club")
fun getAll(): LiveData<List<Club>>
Room's coroutines integration brings ability to return suspend values but when the value itself is asnyc, there is no reason to use it.

I found a good solution to the problem with using rxJava with room and livedata.
The approach is similar to using Retrofit with RxJava, using LiveDataReactiveStreams, which
by default uses flowable.
In your approach i would recomend is:
#Query("SELECT * FROM club")
suspend fun getAll(): LiveData<List<Club>>
changed to
DAO:
#Query("SELECT * FROM club")
fun getAll(): (Any rxJava object) Flowable<List<Club>>
Repository:
fun getAllClubs() : LiveData<List<Club>>{
return LiveDataReactiveStreams.fromPublisher(dao.getAll()"do any transformation or
other functionality you want and then if using Maybe for example transform to
flowable by .toFlowable()")
}
ViewModel:
val clubList : MediatorLiveData<List<Club>>()
fun setClubData(){
clubList.addSource(repository.getAllClubs(), {
clubList.value = it
})
}
then you can observe the livedata object as usual in your view.
Hope what i wrote is understandable, if not i will try to make it better :)

Related

'dagger.hilt.android.internal.lifecycle.DefaultActivityViewModelFactory' could not be resolved

I have spent the hole week trying to add hilt dependency injection to my sample note application, android studio have been throwing on me error after an error.It got me mad, any way, in AppModule i have been trying to inject my room database to app repository and then my app repo to my use cases class and at the end injecting use cases class to my sharedViewModel
so this is my AppModule object:
#Module
#InstallIn(SingletonComponent::class)
object AppModule {
#Provides
#Singleton
fun provideNoteDatabase(app: Application): NoteDatabase {
return Room.databaseBuilder(
app,
NoteDatabase::class.java,
NoteDatabase.DATABASE_NAME
).build()
}
#Provides
#Singleton
fun provideNoteRepository(db: NoteDatabase): NotesRepo {
return RepoImplementation(db.noteDao())
}
#Provides
#Singleton
fun provideNoteUseCase(repo: NotesRepo): NoteUseCase {
return NoteUseCase(
getNotesUseCase = GetNotesUseCase(repo),
deleteNoteUseCase = DeleteNoteUseCase(repo),
updateNoteUseCase = UpdateNoteUseCase(repo),
insertNoteUseCase = InsertNoteUseCase(repo)
)
}
}
and this my Application class:
#HiltAndroidApp
class Application : Application()
my edit fragment:
#AndroidEntryPoint
class EditFragment : Fragment() {
private var _binding: FragmentEditBinding? = null
private val binding get() = _binding!!
private val viewModel: SharedViewModel by activityViewModels()
//...
}
my other fragment:
#AndroidEntryPoint
class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
private val viewModel: SharedViewModel by activityViewModels()
//...
}
by the way also my MainActivity is annotated with #AndroidEntryPoint
my famous viewModel :
#HiltViewModel
class SharedViewModel #Inject constructor(private val noteUseCase: NoteUseCase) :
ViewModel() {...}
this is project level build.gradle:
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
def nav_version = "2.5.2"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.44'
}
}
plugins {
id 'com.android.application' version '7.3.0' apply false
id 'com.android.library' version '7.3.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
}
and module level build.gradle:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android'
id 'kotlin-kapt'
id "androidx.navigation.safeargs"
id 'com.google.dagger.hilt.android'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.stayin"
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'
}
buildFeatures {
dataBinding true
viewBinding true
}
namespace 'com.example.stayin'
}
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 lifecycle_version = "2.4.1"
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// coroutines for getting off the UI thread
def coroutines = "1.6.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
//shared preferences dependency
implementation 'androidx.preference:preference-ktx:1.2.0'
// Room dependency
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
//navigation component dependency
implementation "androidx.navigation:navigation-fragment-ktx:2.5.2"
implementation "androidx.navigation:navigation-ui-ktx:2.5.2"
//Dagger - Hilt
implementation 'com.google.dagger:hilt-android:2.44'
kapt 'com.google.dagger:hilt-compiler:2.44'
// For instrumentation tests
androidTestImplementation 'com.google.dagger:hilt-android-testing:2.44'
kaptAndroidTest 'com.google.dagger:hilt-compiler:2.44'
// For local unit tests
testImplementation 'com.google.dagger:hilt-android-testing:2.44'
kaptTest 'com.google.dagger:hilt-compiler:2.44'
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
}
if can any one help me to find what is wrong and explained why, i will be so thankful towards him. i rally need to pass this so i can level up in my career.
Remove below deprecated dependency:
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
(It was deprecated since dagger-2.34 version)
proof:
https://github.com/google/dagger/releases/tag/dagger-2.34
Also Try to upgrade your lifecycle version as below:
def lifecycle_version = "2.5.1"
add below lines after dependency section in build.gradle(app):
kapt { correctErrorTypes true }
follow official documentation:
https://developer.android.com/training/dependency-injection/hilt-android
https://dagger.dev/hilt/view-model.html

Can't use suspend function in RoomDB Dao

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.

cannot find implementation ( Room )

I have an issue with Room or idk actually where the problem is and I need help to find out where is the problem, I'm using Hilt DI, the moment that creating an instance of database it crashes here's my code
Error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.todo, PID: 1895
java.lang.RuntimeException: cannot find implementation for com.example.todo.data.ToDoDatabase. ToDoDatabase_Impl does not exist
at androidx.room.Room.getGeneratedImplementation(Room.java:97)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:1358)
at com.example.todo.di.AppModule.provideToDoDatabase(AppModule.kt:27)
at com.example.todo.di.AppModule_ProvideToDoDatabaseFactory.provideToDoDatabase(AppModule_ProvideToDoDatabaseFactory.java:33)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.toDoDatabase(DaggerMainApplication_HiltComponents_SingletonC.java:69)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.access$2000(DaggerMainApplication_HiltComponents_SingletonC.java:48)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:583)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.toDoDao(DaggerMainApplication_HiltComponents_SingletonC.java:73)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.access$1900(DaggerMainApplication_HiltComponents_SingletonC.java:48)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:580)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.toDoRepository(DaggerMainApplication_HiltComponents_SingletonC.java:448)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.toDoViewModel(DaggerMainApplication_HiltComponents_SingletonC.java:452)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.access$1700(DaggerMainApplication_HiltComponents_SingletonC.java:429)
at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:487)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$1.create(HiltViewModelFactory.java:100)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:109)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:171)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:44)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:31)
at com.example.todo.fragments.add.AddFragment.getViewModel(AddFragment.kt:20)
at com.example.todo.fragments.add.AddFragment.insertDataToDo(AddFragment.kt:63)
at com.example.todo.fragments.add.AddFragment.onOptionsItemSelected(AddFragment.kt:45)
at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3122)
at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:3226)
at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3126)
at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:3226)
at androidx.fragment.app.FragmentController.dispatchOptionsItemSelected(FragmentController.java:416)
at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:358)
at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:264)
at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
at androidx.appcompat.app.AppCompatDelegateImpl.onMenuItemSelected(AppCompatDelegateImpl.java:1179)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:975)
at androidx.appcompat.widget.ActionMenuView.invokeItem(ActionMenuView.java:624)
at androidx.appcompat.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:151)
at android.view.View.performClick(View.java:7441)
at android.view.View.performClickInternal(View.java:7418)
at android.view.View.access$3700(View.java:835)
at android.view.View$PerformClick.run(View.java:28676)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7842)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'androidx.navigation.safeargs.kotlin'
id 'dagger.hilt.android.plugin'
id 'kotlin-parcelize'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.todo"
minSdk 24
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 {
dataBinding true
viewBinding true
}
}
dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
def nav_version = "2.3.5"
def room_version = "2.3.0"
def lifecycle_version = "2.4.0"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
testImplementation 'junit:junit:'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//Navigation component
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
//Room
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// Lifecycle
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
//Kotlin coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
//RecyclerView
implementation 'jp.wasabeef:recyclerview-animators:4.0.2'
//Hilt DI
implementation "com.google.dagger:hilt-android:2.38.1"
kapt "com.google.dagger:hilt-compiler:2.38.1"
}
ToDoData.kt
#Entity(tableName = "todo_table")
#Parcelize
data class ToDoData(
#PrimaryKey(autoGenerate = true)
var id: Int,
var title: String,
var description: String,
var priority: Priority
) : Parcelable
ToDoDatabase.kt
#Database(entities = [ToDoData::class], version = 1, exportSchema = false)
#TypeConverters(Converter::class)
abstract class ToDoDatabase : RoomDatabase() {
abstract fun toDoDao(): ToDoDao
}
ToDoViewModel.kt
#HiltViewModel
class ToDoViewModel #Inject constructor(
private val repository: ToDoRepository
) : ViewModel() {
private val getAllData: LiveData<List<ToDoData>> = repository.getAllData
fun insertData(toDoData: ToDoData) {
viewModelScope.launch(Dispatchers.IO) {
repository.insertData(toDoData)
}
}
}
AppModule.kt
#Module
#InstallIn(SingletonComponent::class)
object AppModule {
#Singleton
#Provides
fun provideToDoDatabase(
#ApplicationContext app: Context
) = Room.databaseBuilder(
app,
ToDoDatabase::class.java,
"todo_database"
)
.fallbackToDestructiveMigration()
.build()
#Singleton
#Provides
fun provideTodoDao(db: ToDoDatabase) = db.toDoDao()
}
AddFragment.kt
And here's the function that I call to insert data from AddFragment
private val viewModel: ToDoViewModel by viewModels()
private fun insertDataToDo() {
val title = binding.titleEt.text.toString()
val priority = binding.spinnerPriorities.selectedItem.toString()
val description = binding.descriptionEt.text.toString()
val validation = verifyDataFromUser(title, description)
if (validation) {
val data = ToDoData(
0,
title,
description,
parsePriority(priority)
)
viewModel.insertData(data)
Toast.makeText(requireContext(), "Successfully Added!", Toast.LENGTH_SHORT).show()
findNavController().navigate(R.id.action_addFragment_to_listFragment)
} else
Toast.makeText(requireContext(), "Please fill out all fields", Toast.LENGTH_SHORT)
.show()
}
private fun verifyDataFromUser(title: String, description: String): Boolean {
return if (TextUtils.isEmpty(title) || TextUtils.isEmpty(description)) {
false
} else !(title.isEmpty() || description.isEmpty())
}
private fun parsePriority(priority: String): Priority {
return when (priority) {
"High Priority" -> Priority.HIGH
"Medium Priority" -> Priority.MEDIUM
"Low Priority" -> Priority.LOW
else -> Priority.LOW
}
}
I have already seen some questions here with the same problem but it didn't work for me so idk exactly where the problem here
I had exactly the same problem as you, and after half a day of trying to rewrite and delete the pieces of code, finally my problem was solved by changing annotationProcessor to kapt in the build.gradle file.
// Hilt, Dependency injection
def hilt_version = "2.38.1"
implementation "com.google.dagger:hilt-android:$hilt_version"
annotationProcessor "com.google.dagger:hilt-compiler:$hilt_version"
// Room database
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
After change and fixed:
// Hilt, Dependency injection
def hilt_version = "2.38.1"
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"
// Room database
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
Given the error text that was printed on the console, I did not think it was a problem at all!

using Room with kotlin, get exception when build the database

UPDATE: tried Mike's suggestion, still get error:
ext {
kotlin_version = '1.1.50'
arch_lib_version = '1.0.0-alpha9'
gradle_version = '2.3.3'
}
kapt {
generateStubs = true
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile "android.arch.lifecycle:runtime:$arch_lib_version"
compile "android.arch.lifecycle:extensions:$arch_lib_version"
compile "android.arch.persistence.room:runtime:$arch_lib_version"
//annotationProcessor "android.arch.persistence.room:compiler:$arch_lib_version"
kapt "android.arch.persistence.room:compiler:$arch_lib_version"
annotationProcessor "android.arch.lifecycle:compiler:$arch_lib_version"
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
Error:Annotation processor '__gen.AnnotationProcessorWrapper_robotiumDebug_android_arch_persistence_room_RoomProcessor' not found
============
in gradle:
ext {
arch_lib_version = '1.0.0-alpha9'
}
compile "android.arch.persistence.room:runtime:$arch_lib_version"
annotationProcessor "android.arch.persistence.room:compiler:$arch_lib_version"
//kapt "android.arch.persistence.room:compiler:$arch_lib_version"
tried using the kapt, it will give compile error:
Error:Annotation processor '__gen.AnnotationProcessorWrapper_robotiumDebug_android_arch_persistence_room_RoomProcessor' not found
the code snippet is below:
#Database(entities = arrayOf(CModel::class), version = 1)
abstract class CDatabase : RoomDatabase() {
abstract fun cModel(): DbCDao
companion object {
fun getDatabase(context: Context): CDatabase {
return Room.databaseBuilder(context.applicationContext, CDatabase::class.java, “database”)
.build() //<=== throw here saying CDatabase_Impl does not exist
}
}
}
the table clas:
#Entity(tableName = “table”)
class CModel() : ICDelegate {
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = “index")
private var mIndex: Long = -1
#ColumnInfo(name = "parentIndex")
private var mParentIndex: Long = -1
……
}
the Dao interface defination:
#Dao
interface DbCDao {
#Query("select * from table")
fun loadAllAccountss(): List<CModel>
#Query("select * from table where index = :index")
fun loadCsByIndex(index: Int): CModel
#Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertC(ac: CModel) : Long
#Update(onConflict = OnConflictStrategy.REPLACE)
fun updateAC(ac: CModel) : Int
#Delete
fun deleteAc(ac: CModel) : Int
#Query("DELETE FROM table”)
fun deleteAllCs()
}
the exception:
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by:
java.lang.RuntimeException: cannot find implementation for com.myproject.data. CDatabase. CDatabase_Impl does not exist
at
android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:90)
at
android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:440)
tried someone suggested and does not work:
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
This is my workable build.gradle file:
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
...
kapt {
generateStubs = true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'commons-io:commons-io:2.5'
compile "android.arch.persistence.room:runtime:1.0.0-alpha9-1"
kapt "android.arch.persistence.room:compiler:1.0.0-alpha9-1"
}
Take into account:
apply plugin: 'kapt' is removed.
kapt {
generateStubs = true
}
compile instead on implementation.
I used Kotlin 1.1.50.

Room Persistence lib implementation in Kotlin

I am implementing Room persistence lib in kotlin for my database implementation.
Following are my Entity, Dao and Database classes:
Food.kt
#Entity
class Food(#ColumnInfo(name = "food_name") var foodName: String,
#ColumnInfo(name = "food_desc") var foodDesc: String,
#ColumnInfo(name = "protein") var protein: Double,
#ColumnInfo(name = "carbs") var carbs: Double,
#ColumnInfo(name = "fat") var fat: Double)
{
#ColumnInfo(name = "id")
#PrimaryKey(autoGenerate = true)
var id: Long = 0
#ColumnInfo(name = "calories")
var calories: Double = 0.toDouble()
}
PersonalizedFood.kt
#Entity(primaryKeys = arrayOf("food_id","date"))
class PersonalizedFood(#ColumnInfo(name = "quantity") var quantity: Int,
#ColumnInfo(name = "unit") var unit: String,
#ColumnInfo(name = "date") var date: Date){
#ColumnInfo(name = "food_id")
var foodId:Long = 0
}
FoodDao.kt
#Dao
interface FoodDao {
companion object{
const val ID = "id"
const val NAME = "name"
const val PROTEIN = "protein"
const val DESC = "desc"
const val CARBS = "carbs"
const val FAT = "fat"
const val DATE = "date"
const val FOOD_ID = "food_id"
const val ALL_FOOD_LIST = "food"
const val PERSONALISED_FOOD_LIST = "personalised_food"
}
/**
* Returns food details of a food given by food_id
*/
#Query("SELECT * FROM $ALL_FOOD_LIST WHERE $ID=:food_id")
fun getFoodDetails(food_id:Long):Food
/**
* Inserts food items in all_food_list
*/
#Insert
fun addFoodList(list:ArrayList<Food>)
#Insert(onConflict = REPLACE)
fun saveFood(food:PersonalizedFood)
#Query("SELECT * FROM $PERSONALISED_FOOD_LIST WHERE $FOOD_ID=:foodId and $DATE=:date")
fun getFood(foodId:Int, data:Date):PersonalizedFood
#Query("SELECT * FROM $ALL_FOOD_LIST where $ID in (select $FOOD_ID from $PERSONALISED_FOOD_LIST where $DATE = :date)")
fun getFood(date:Date):ArrayList<Food>
}
Converter.kt
class Converter {
companion object{
#TypeConverter
fun fromTimestamp(value: Long?): Date? {
return if (value == null) null else Date(value)
}
#TypeConverter
fun dateToTimestamp(date: Date): Long {
return date.time
}
}
}
FoodDatabase.kt
#Database(entities = arrayOf(Food::class, PersonalizedFood::class), version = 1)
#TypeConverters(Converter::class)
abstract class FoodDatabase : RoomDatabase(){
abstract fun foodDao():FoodDao
companion object{
private val databaseName = "diet"
var dbInstance:FoodDao? = null
fun getInstance(context:Context):FoodDao?{
if(dbInstance == null)
dbInstance = Room.inMemoryDatabaseBuilder(context, FoodDatabase::class.java).build().foodDao()
return dbInstance;
}
}
}
And when i run following code to create database:
FoodDatabase.getInstance(baseContext)?.getFood(Calendar.getInstance().time)
It gives me following exception:
Caused by: java.lang.RuntimeException: cannot find implementation for
com.chandilsachin.diettracker.database.FoodDatabase. FoodDatabase_Impl
does not exist
at
android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:90)
at
android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:340)
at
com.chandilsachin.diettracker.database.FoodDatabase$Companion.getInstance(FoodDatabase.kt:21)
at
com.chandilsachin.diettracker.MainActivity$SetUpFoodDatabase.doInBackground(MainActivity.kt:95)
at
com.chandilsachin.diettracker.MainActivity$SetUpFoodDatabase.doInBackground(MainActivity.kt:77)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818)
Has anyone implemented room persistence in kotlin?
Edited
This question was marked duplicate of this. Though problem statement is same but solution given does not solve my problem. Solution says i have to add replace annotationProcessor to kapt "android.arch.persistence.room:compiler:1.0.0-alpha1" dependency. I made those changes and it resulted in gradle error while project build.
Information:Gradle tasks [:app:assembleDebug] Warning:warning:
Supported source version 'RELEASE_7' from annotation processor
'android.arch.persistence.room.RoomProcessor' less than -source '1.8'
Warning:warning: The following options were not recognized by any
processor: '[kapt.kotlin.generated]'
/Users/BBI-M1025/Documents/BBI/Workspace_fun/Android/diet-tracker/app/src/main/java/com/chandilsachin/diettracker/database/Food.kt
Error:(1, 1) Some error(s) occurred while processing annotations. Please see the error messages above.
Error:Execution failed for task ':app:kaptDebugKotlin'.
Compilation error. See log for more details
Information:BUILD FAILED in 10s
Information:2 errors
Information:2 warnings
Information:See complete output in console
I am attaching my gradle file also:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.chandilsachin.diettracker"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'
compile 'com.android.support:cardview-v7:25.0.1'
compile 'com.android.support:recyclerview-v7:25.0.1'
compile 'com.github.ne1c:rainbowmvp:1.2.1'
compile "org.jetbrains.anko:anko-commons:0.10.0"
/*annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"*/
compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
kapt "android.arch.persistence.room:compiler:1.0.0-alpha1"
testCompile 'junit:junit:4.12'
}
repositories {
mavenCentral()
}
Has anyone come across this issue?
After spinning my head around for a while with this problem, I came across to the solution.
It was really hard as there is no official tutorial, blog etc out there to help with this problem as of now.
I had to do several hit and trial for all the combination of gradle plugins and dependencies as i knew that something is wrong with gradle config only.
Lets come to the solution:
I had to remove apply plugin: 'kotlin-kapt' from build.gradle(:module) file
and replace annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1" to kapt "android.arch.persistence.room:compiler:1.0.0-alpha1".
This is the gradle configuration to successfully compile code.
But there more things to check. You have to initialise properties of your #Entity class unlike java given in Room Persistence lib doc. Though there are getter setter but it is not mentioned to create a constructor with initialisation.
So I had to change my #Entity class with this:
#Entity(tableName = "all_food_list")
class Food (#ColumnInfo(name = "food_name") var foodName: String = "",
#ColumnInfo(name = "food_desc") var foodDesc: String = "",
#ColumnInfo(name = "protein") var protein: Double = 0.0,
#ColumnInfo(name = "carbs") var carbs: Double = 0.0,
#ColumnInfo(name = "fat") var fat: Double = 0.0,
#ColumnInfo(name = "calories") var calories: Double = 0.0)
{
#ColumnInfo(name = "id")
#PrimaryKey(autoGenerate = true)
var id: Long = 0
}
Now for TypeConverts, Unlike java, you need to create normal function not static functions(companion object):
class Converters{
#TypeConverter
fun fromTimestamp(value: String): Calendar {
val arr = value.split("-")
val cal = Calendar.getInstance()
cal.set(arr[0].toInt(), arr[1].toInt(), arr[2].toInt())
return cal
}
#TypeConverter
fun dateToTimestamp(date: Calendar): String {
return "${date.get(Calendar.DATE)}-${date.get(Calendar.MONTH)+1}-${date.get(Calendar.YEAR)}"
}
}
I am adding build.gradle file also to make it more clear:
build.gradle(:project)
buildscript {
ext.kotlin_version = '1.1.2-4'
ext.gradle_version_stable = '2.3.2'
ext.gradle_version_preview = '3.0.0-alpha1'
ext.anko_version = '0.10.0'
repositories {
maven { url 'https://maven.google.com' }
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url 'https://maven.google.com' }
jcenter()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
build.gradle(:module)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.chandilsachin.diettracker"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
...
...
// room persistence dependency
compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
kapt "android.arch.persistence.room:compiler:1.0.0-alpha1"
testCompile 'junit:junit:4.12'
}
repositories {
mavenCentral()
}
I think this is all, I did to make my code woking.
Hope this helps someone else also.
Here my gradle files, i didn't need to add thoses plugins.
build.gradle(project):
buildscript {
ext.kotlin_version = '1.1.2-4'
ext.lifecycle_version = '1.0.0-alpha1'
ext.room_version = '1.0.0-alpha1'
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
build.gradle (app)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
//enable anotation processing with kotlin, disabled by default
kapt {
generateStubs = true
}
android {
/**
...
**/
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//kotlin
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
//support
compile 'com.android.support:appcompat-v7:25.3.1'
//google architecture
compile "android.arch.lifecycle:runtime:$lifecycle_version"
compile "android.arch.lifecycle:extensions:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
kapt "android.arch.lifecycle:compiler:$lifecycle_version"
//database
compile "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
}
repositories {
mavenCentral()
}
Then run menu build-> make project to create impl class.
Hope this helps
I made an example similar using Java and used to have same problem and solution was add APT line apt "android.arch.persistence.room:compiler:1.0.0-alpha1"
without apply: apply plugin: 'kotlin-kapt'. Remove this line!!
You have to clear project and rebuild it before run again and try uninstall existing app on phone or Virtual device.
Hope you help.
I got the same issue when I try to migrate from Java to Kotlin:
RuntimeException: cannot find implementation for AppDatabase. AppDatabase_Impl does not exist
I tried all these answers in this question, none all them works, then I found an article: Kotlinlang Tutorials - Android Frameworks Using Annotation Processing:
In Kotlin you specify the dependencies in a similar to Java way using Kotlin Annotation processing tool (kapt) instead of annotationProcessor.
Then I modified the build.gradle(Module:app) by changing all annotationProcessor to kapt, it works:
--- a/app/build.gradle
+++ b/app/build.gradle
## -2,6 +2,8 ## apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
android {
// Butter Knife
implementation "com.jakewharton:butterknife:$butterknife_version"
- annotationProcessor "com.jakewharton:butterknife-compiler:$butterknife_version"
+ kapt "com.jakewharton:butterknife-compiler:$butterknife_version"
// Room
implementation "android.arch.persistence.room:runtime:$arch_lifecycle_version"
- annotationProcessor "android.arch.persistence.room:compiler:$arch_lifecycle_version"
+ kapt "android.arch.persistence.room:compiler:$arch_lifecycle_version"
// LifeCycle
implementation "android.arch.lifecycle:runtime:$arch_lifecycle_version"
implementation "android.arch.lifecycle:extensions:$arch_lifecycle_version"
implementation "android.arch.lifecycle:common-java8:$arch_lifecycle_version"
- annotationProcessor "android.arch.lifecycle:compiler:$arch_lifecycle_version"
+ kapt "android.arch.lifecycle:compiler:$arch_lifecycle_version"
// Dagger
implementation "com.google.dagger:dagger:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version"
- annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
- annotationProcessor "com.google.dagger:dagger-android-processor:$dagger_version"
+ kapt "com.google.dagger:dagger-compiler:$dagger_version"
+ kapt "com.google.dagger:dagger-android-processor:$dagger_version"
}
If you use Butter Knife, you should also change to kapt, otherwise the views which are injected might be null.
in the Dao interface check that the annotations like #Query .. are imported from the room database class and not from somewhere else

Categories

Resources