无法在Kotlin中创建com.example ... ViewModel类的实例

时间:2020-09-07 01:09:08

标签: android kotlin android-room

在有人说这之前已经被回答之前,我已经阅读并尝试了下面列出的帖子中的推荐解决方案:

  1. Cannot create an instance of class - ViewModel
  2. Cannot create an instance of custom ViewModel
  3. Cannot Create Instance Of Class ViewModel
  4. Cannot create an instance of class ViewModel in Android MVVM
  5. Kotlin cannot create an instance of ViewModel
  6. Cannot create an instance of class ViewModel

我尝试在build.gradle文件中添加依赖项,尝试使用ViewModel类的不同实现,但没有任何改变。

我得到的主要错误是

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

在下面,我列出了我当前的相关代码。如果您认为缺少重要的代码,请告诉我。

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
    }
}

存储库

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
}

问题

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

主要活动(部分)

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)
    }
.
.
.
}

数据库

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
            }
        }
    }
}

错误消息

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'

我无法立即解决此问题。谢谢您的提前帮助。

0 个答案:

没有答案