Before someone says this has been answered before, I've read and tried the recommended solutions in the posts listed below:
- Cannot create an instance of class - ViewModel
- Cannot create an instance of custom ViewModel
- Cannot Create Instance Of Class ViewModel
- Cannot create an instance of class ViewModel in Android MVVM
- Kotlin cannot create an instance of ViewModel
- Cannot create an instance of class ViewModel
I have tried adding dependencies in the build.gradle file, trying different implementations of my ViewModel class and nothing has changed.
The main error I get is
Process: com.example.infinityquiz, PID: 12107
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.infinityquiz/com.example.infinityquiz.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.infinityquiz.viewmodel.QuestionViewModel
Below I listed my current relevant code. If you think important code is missing, please let me know.
Build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'androidx.navigation.safeargs.kotlin'
android {
compileSdkVersion 29
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "com.example.infinityquiz"
minSdkVersion 23
targetSdkVersion 29
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 = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// Navigation Component
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
// Room components
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
implementation "androidx.room:room-ktx:2.2.5"
androidTestImplementation "androidx.room:room-testing:2.2.5"
implementation "androidx.paging:paging-runtime:2.1.2"
// 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.7"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5"
// Extensions = ViewModel + LiveData
implementation "android.arch.lifecycle:extensions:1.1.1"
kapt "android.arch.lifecycle:compiler:1.1.1"
// Room
implementation "android.arch.persistence.room:runtime:1.1.1"
kapt "android.arch.persistence.room:compiler:1.1.1"
implementation 'androidx.fragment:fragment:1.2.5'
}
ViewModel
package com.example.infinityquiz.viewmodel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import com.example.infinityquiz.data.QuestionDatabase
import com.example.infinityquiz.model.Question
import com.example.infinityquiz.repository.QuestionRepository
class QuestionViewModel(application: Application): AndroidViewModel(application) {
val question: Question
private val repository:QuestionRepository
init {
val questionDao = QuestionDatabase.getDatabase(
application
).questionDao()
repository = QuestionRepository(questionDao)
question = repository.question
}
}
Repository
package com.example.infinityquiz.repository
import com.example.infinityquiz.data.QuestionDao
import com.example.infinityquiz.model.Question
class QuestionRepository(private val questionDao: QuestionDao) {
val question: Question = questionDao.readRandomQuestion()
}
Dao
package com.example.infinityquiz.data
import androidx.room.Dao
import androidx.room.Query
import com.example.infinityquiz.model.Question
/*
private const val TABLE_NAME = "multiple_choice_questions"
private const val QUERY = "SELECT * FROM $TABLE_NAME ORDER BY RANDOM() LIMIT 1"
*/
@Dao
interface QuestionDao {
@Query("SELECT * FROM multiple_choice_questions ORDER BY RANDOM() LIMIT 1")
fun readRandomQuestion(): Question
}
Question
package com.example.infinityquiz.model
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize
@Parcelize
@Entity(tableName = "multiple_choice_questions")//, foreignKeys=[], indices=[])
data class Question (
@PrimaryKey(autoGenerate = true)
val id: Int,
val Question: String,
val Category: String,
val Subcategory: String,
val AnswerOne: String,
val AnswerTwo: String,
val AnswerThree: String,
val AnswerFour: String,
val CorrectAnswer: Int,
val wasQuestionSeen: Int,
val Wikipedia: String
): Parcelable
Main Activity(portions of)
package com.example.infinityquiz
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import com.example.infinityquiz.model.Question
import com.example.infinityquiz.viewmodel.QuestionViewModel
import kotlinx.android.synthetic.main.activity_quiz_questions.*
class MainActivity : AppCompatActivity(), View.OnClickListener{
private lateinit var mQuestionViewModel: QuestionViewModel
private var question: Question? = null
private var mSelectedOptionPosition: Int = 0
/**
* This function is auto created by Android when the Activity Class is created.
*/
override fun onCreate(savedInstanceState: Bundle?) {
//This call the parent constructor
super.onCreate(savedInstanceState)
// This is used to align the xml view to this class
setContentView(R.layout.activity_main)
mQuestionViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.application)).get(QuestionViewModel::class.java)
// mQuestionViewModel = ViewModelProvider(this).get(QuestionViewModel::class.java)
setQuestion()
tv_option_one.setOnClickListener(this)
tv_option_two.setOnClickListener(this)
tv_option_three.setOnClickListener(this)
tv_option_four.setOnClickListener(this)
btn_submit.setOnClickListener(this)
}
.
.
.
}
Database
package com.example.infinityquiz.data
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.example.infinityquiz.model.Question
@Database(entities = [Question::class], version = 1)
abstract class QuestionDatabase: RoomDatabase() {
abstract fun questionDao(): QuestionDao
companion object {
@Volatile
private var INSTANCE: QuestionDatabase? = null
private const val PATH = "database/data_eng.db"
private const val NAME = "multiple_choice_questions"
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context.applicationContext, QuestionDatabase::class.java, NAME).createFromAsset(PATH).build()
fun getDatabase(context: Context): QuestionDatabase{
val tempInstance = INSTANCE
if(tempInstance != null){
return tempInstance
}
synchronized(this){
val instance = buildDatabase(context)
INSTANCE = instance
return instance
}
}
}
}
Error message
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.infinityquiz, PID: 12107
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.infinityquiz/com.example.infinityquiz.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.infinityquiz.viewmodel.QuestionViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.infinityquiz.viewmodel.QuestionViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:275)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.infinityquiz.MainActivity.onCreate(MainActivity.kt:32)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.infinityquiz.MainActivity.onCreate(MainActivity.kt:32)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.IllegalStateException: Pre-packaged database has an invalid schema: multiple_choice_questions(com.example.infinityquiz.model.Question).
Expected:
TableInfo{name='multiple_choice_questions', columns={Category=Column{name='Category', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, Subcategory=Column{name='Subcategory', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, wasQuestionSeen=Column{name='wasQuestionSeen', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, AnswerThree=Column{name='AnswerThree', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, Wikipedia=Column{name='Wikipedia', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, Question=Column{name='Question', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, AnswerOne=Column{name='AnswerOne', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, CorrectAnswer=Column{name='CorrectAnswer', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, AnswerTwo=Column{name='AnswerTwo', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, AnswerFour=Column{name='AnswerFour', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='multiple_choice_questions', columns={}, foreignKeys=[], indices=[]}
at androidx.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:163)
E/AndroidRuntime: at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:135)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:142)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:428)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:317)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:92)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:53)
at androidx.room.SQLiteCopyOpenHelper.getWritableDatabase(SQLiteCopyOpenHelper.java:90)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:281)
at com.example.infinityquiz.data.QuestionDao_Impl.readRandomQuestion(QuestionDao_Impl.java:25)
at com.example.infinityquiz.repository.QuestionRepository.<init>(QuestionRepository.kt:7)
at com.example.infinityquiz.viewmodel.QuestionViewModel.<init>(QuestionViewModel.kt:17)
... 21 more
Disconnected from the target VM, address: 'localhost:8608', transport: 'socket'
I cannot find an immediate fix to this problem. Thank you for your help in advance.