Это мой первый проект, использующий Kotlin, поэтому я практикую создание приложения и использование компонентов архитектуры Room Database, Android View Model и LiveData, но я получил это сообщение об ошибке. И мобильный кр sh неожиданно,
Я не знаю, как это решить.
Спасибо.
build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "kotlin-kapt"
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.leaf76.architectureexample"
minSdkVersion 21
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'
}
}
}
dependencies {
def lifecycle_version = "2.2.0"
def room_version = "2.2.5"
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
// com.android.support.cardview => androidx
implementation "androidx.cardview:cardview:1.0.0"
// com.android.support.design => androidx
implementation "com.google.android.material:material:1.0.0"
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// Room
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
}
Сообщение об ошибке
2020-03-27 02:50:27.987 12708-12708/com.leaf76.architectureexample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.leaf76.architectureexample, PID: 12708
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.leaf76.architectureexample/com.leaf76.architectureexample.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.leaf76.architectureexample.NoteViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3448)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
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:2147)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7811)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.leaf76.architectureexample.NoteViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.leaf76.architectureexample.MainActivity.onCreate(MainActivity.kt:21)
at android.app.Activity.performCreate(Activity.java:7955)
at android.app.Activity.performCreate(Activity.java:7944)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3423)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
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:2147)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7811)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)
Caused by: java.lang.InstantiationException: java.lang.Class<com.leaf76.architectureexample.NoteViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.leaf76.architectureexample.MainActivity.onCreate(MainActivity.kt:21)
at android.app.Activity.performCreate(Activity.java:7955)
at android.app.Activity.performCreate(Activity.java:7944)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3423)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
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:2147)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7811)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)
Note.kt
package com.leaf76.architectureexample
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "note_table")
data class Note(var title: String, var description: String, var priorty: Int) {
@PrimaryKey(autoGenerate = true)
var Id: Int = 0
}
NoteDatabase
package com.leaf76.architectureexample
import android.content.Context
import android.os.AsyncTask
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
@Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDatabase : RoomDatabase() {
abstract fun noteDao(): NoteDao
// static parameters
companion object {
private lateinit var instance: NoteDatabase
fun getInstance(context: Context): NoteDatabase {
if (instance == null) {
synchronized(NoteDatabase::class.java) {
instance = Room.databaseBuilder(
context.applicationContext,
NoteDatabase::class.java, "note_database"
)
.fallbackToDestructiveMigration()
.addCallback(roomCallbackL)
.build()
}
}
return instance
}
private val roomCallbackL: Callback = object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
PopulateDbAsyncTask(instance).execute()
}
}
private class PopulateDbAsyncTask(db: NoteDatabase) : AsyncTask<Void, Void, Void>() {
private val noteDao: NoteDao = db.noteDao()
override fun doInBackground(vararg voids: Void): Void? {
noteDao.insert(Note("Title1", "Description1", 1))
noteDao.insert(Note("Title2", "Description2", 2))
noteDao.insert(Note("Title3", "Description3", 3))
return null
}
}
}
}
NoteRepository package com.leaf76.architectureexample
import android.app.Application
import android.os.AsyncTask
import androidx.lifecycle.LiveData
class NoteRepository(application: Application) {
// The lateinit avoid Nullable
private var noteDao: NoteDao
private var allNotes: LiveData<List<Note>>
init {
val database = NoteDatabase.getInstance(application.applicationContext)
noteDao = database.noteDao()
allNotes = noteDao.getAllNotes()
}
fun insert(note: Note) {
InsertNoteAsyncTask(noteDao).execute(note)
}
fun update(note: Note) {
UpdateNoteAsyncTask(noteDao).execute(note)
}
fun delete(note: Note) {
DeleteNoteAsyncTask(noteDao).execute(note)
}
fun deleteAllnotes() {
DeleteAllNotesAsyncTask(noteDao).execute()
}
fun getAllNotes(): LiveData<List<Note>> {
return allNotes
}
companion object {
// Insert note
private class InsertNoteAsyncTask(var noteDao: NoteDao) :
AsyncTask<Note, Void, Void>() {
override fun doInBackground(vararg notes: Note): Void? {
noteDao.insert(notes[0])
return null
}
}
// Update note
private class UpdateNoteAsyncTask(var noteDao: NoteDao) :
AsyncTask<Note, Void, Void>() {
override fun doInBackground(vararg notes: Note): Void? {
noteDao.update(notes[0])
return null
}
}
// Delete note
private class DeleteNoteAsyncTask(var noteDao: NoteDao) :
AsyncTask<Note, Void, Void>() {
override fun doInBackground(vararg notes: Note): Void? {
noteDao.delete(notes[0])
return null
}
}
// Delete all note
private class DeleteAllNotesAsyncTask(var noteDao: NoteDao) :
AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg voids: Void): Void? {
noteDao.deleteAllNotes()
return null
}
}
}
}
NoteViewModel
package com.leaf76.architectureexample
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
class NoteViewModel(application: Application) : AndroidViewModel(application) {
private var repository: NoteRepository = NoteRepository(application)
private var allNotes: LiveData<List<Note>> = repository.getAllNotes()
fun insert(note: Note){
repository.insert(note)
}
fun update(note:Note){
repository.update(note)
}
fun delete(note: Note){
repository.delete(note)
}
fun deleteAllNotes(){
repository.deleteAllnotes()
}
fun getAllNotes(): LiveData<List<Note>>{
return allNotes
}
}
MainActivity
package com.leaf76.architectureexample
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
class MainActivity : AppCompatActivity() {
private val TAG: String = "MainActivity"
private lateinit var noteViewModel: NoteViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.i(TAG,"MainActivity entry on create")
noteViewModel = ViewModelProvider(this).get(NoteViewModel::class.java)
Log.i(TAG,"Get note view model")
noteViewModel.getAllNotes().observe(this, Observer<List<Note>> {
Toast.makeText(this,"onChanged",Toast.LENGTH_LONG).show()
})
Log.i(TAG, "Get Toast")
}
}