无法获取NoteViewModel实例致Scribble笔记应用崩溃
笔记应用Scribble启动崩溃问题解决
问题概况
应用名称:Scribble
功能:基础笔记记录应用
问题:应用启动时崩溃,提示无法创建NoteViewModel实例,原因是该类没有无参构造函数。
主活动代码
class MainActivity : AppCompatActivity(), ClickListeners { lateinit var recyclerView : RecyclerView lateinit var addButton : FloatingActionButton lateinit var viewModel : NoteViewModel lateinit var adapter : NoteViewAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) recyclerView = findViewById(R.id.NotesRV) addButton = findViewById(R.id.addButton) viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(NoteViewModel::class.java) addButton.setOnClickListener{ val intent : Intent = Intent(this,AddNoteActivity::class.java) startActivity(intent) } showAllNotes() } override fun onNoteClick(note: Note) { TODO("Not yet implemented") } override fun onDeleteButtonClick(note: Note) { TODO("Not yet implemented") } override fun onNoteLongClick(note: Note) { TODO("Not yet implemented") } fun showAllNotes(){ viewModel.allNotes.observe(this, Observer {list -> adapter = NoteViewAdapter(list as ArrayList<Note>,this, this) recyclerView.adapter = adapter recyclerView.layoutManager = GridLayoutManager(this,2,GridLayoutManager.VERTICAL,false) }) }
问题代码行
ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(NoteViewModel::class.java)
ViewModel类代码
class NoteViewModel (application: Application) : ViewModel() { val allNotes: LiveData<List<Note>> val repository: NoteRepository init { val dao = NoteDatabase.getDatabase(application).getNotesDao() repository = NoteRepository(dao) allNotes = repository.allNotes } fun insertNote(note: Note) { viewModelScope.launch(Dispatchers.IO){ repository.insertNote(note) } } fun deleteNote(note: Note) = viewModelScope.launch(Dispatchers.IO){repository.deleteNote(note)} fun updateNote(note: Note) = viewModelScope.launch(Dispatchers.IO){repository.updateNote(note)}
Logcat日志
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.scribble/com.example.scribble.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.scribble.model.NoteViewModel at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 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:2210) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) 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) Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.scribble.model.NoteViewModel at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:188) at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238) at com.example.scribble.MainActivity.onCreate(MainActivity.kt:31) at android.app.Activity.performCreate(Activity.java:8051) at android.app.Activity.performCreate(Activity.java:8031) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 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:2210) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) 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) Caused by: java.lang.InstantiationException: java.lang.Class<com.example.scribble.model.NoteViewModel> has no zero argument constructor at java.lang.Class.newInstance(Native Method) at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:186) at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238) at com.example.scribble.MainActivity.onCreate(MainActivity.kt:31) at android.app.Activity.performCreate(Activity.java:8051) at android.app.Activity.performCreate(Activity.java:8031) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 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:2210) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) 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)
错误核心原因
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.scribble.model.NoteViewModel> has no zero argument constructor
解决方案
问题出在NoteViewModel的继承类选择上,只需修改一处即可解决:
修改ViewModel继承类:
由于你的NoteViewModel需要接收Application参数,应该继承AndroidViewModel而非ViewModel——AndroidViewModel是专门为需要Application实例的场景设计的,自带对Application参数的支持。修改后的代码如下:class NoteViewModel(application: Application) : AndroidViewModel(application) { val allNotes: LiveData<List<Note>> val repository: NoteRepository init { val dao = NoteDatabase.getDatabase(application).getNotesDao() repository = NoteRepository(dao) allNotes = repository.allNotes } fun insertNote(note: Note) { viewModelScope.launch(Dispatchers.IO) { repository.insertNote(note) } } fun deleteNote(note: Note) = viewModelScope.launch(Dispatchers.IO) { repository.deleteNote(note) } fun updateNote(note: Note) = viewModelScope.launch(Dispatchers.IO) { repository.updateNote(note) } }保留原实例化代码:
你原来的ViewModel实例化代码是正确的,AndroidViewModelFactory会自动处理Application参数的传递,无需修改:viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(NoteViewModel::class.java)
修改完成后,AndroidViewModelFactory就能正确识别NoteViewModel的构造函数,成功创建实例,解决启动崩溃问题。
内容的提问来源于stack exchange,提问作者vibhum mohan
相关产品推荐
相关产品推荐

