无法创建ViewModel类的实例 kotlin
无法创建ViewModel类的实例 kotlin
这是我的代码:
class BookmarkViewModel(app: Application) : AndroidViewModel(app) {
private val dao = BookmarkDb.get(app).bookmarkDao()
companion object {
private const val PAGE_SIZE = PagingConstants.PERPAGE
/**
* 如果启用了占位符,PagedList将报告完整的大小,但在onBind方法中可能会有一些项为空(当数据加载时,PagedListAdapter会触发重新绑定)。
*
* 如果禁用了占位符,onBind将永远不会接收到null,但是随着加载更多的页面,滚动条会在加载新页面时抖动。如果禁用了占位符,您应该禁用滚动条。
*/
private const val ENABLE_PLACEHOLDERS = true
}
val allBookmarks = LivePagedListBuilder(dao.allBookmarkByDatetime(), PagedList.Config.Builder()
.setPageSize(PAGE_SIZE)
.setEnablePlaceholders(ENABLE_PLACEHOLDERS)
.build()).build()
fun insert(title: String, description: String, datetime: String) = ioThread {
dao.insert(Bookmark(id = 0, title = title, description = description, datetime = datetime))
}
fun remove(bookmark: Bookmark) = ioThread {
dao.delete(bookmark)
}
}
这是来自Google样本的代码。
之后我想要:
class BookmarkListFragment : FirstFragment() {
private var viewModel: BookmarkViewModel? = null
..
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(activity!!).get(BookmarkViewModel::class.java)
...
这里出现了问题:
java.lang.RuntimeException: 无法创建类com.lacas.db.room.BookmarkViewModel的实例
我可以在Fragment中使用吗?
java.lang.RuntimeException: 无法启动活动ComponentInfo{com.lacas.asd/com.lacas.asd.ui.activities.testtabs.TestTab2Activity}:java.lang.RuntimeException:无法创建类com.lacas.asd.db.room.BookmarkViewModel的实例
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2924)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Caused by: java.lang.RuntimeException: 无法创建类com.lacas.asd.db.room.BookmarkViewModel的实例
at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:207)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:34)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:29)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:154)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity.getViewModel(TestTab2Activity.kt)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity.onCreated(TestTab2Activity.kt:45)
at com.lacas.asd.base.BasePermissionsActivity.onCreate(BasePermissionsActivity.kt:34)
at android.app.Activity.performCreate(Activity.java:6912)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2877)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:199)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:34)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:29)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:154)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity.getViewModel(TestTab2Activity.kt)
at com.lacas.asd.ui.activities.testtabs.TestTab2Activity.onCreated(TestTab2Activity.kt:45)
at com.lacas.asd.base.BasePermissionsActivity.onCreate(BasePermissionsActivity.kt:34)
at android.app.Activity.performCreate(Activity.java:6912)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2877)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
问题的原因是在最新版本的Android Studio中,添加了kapt会导致构建错误,提示"app: Original kapt is deprecated.",因此需要在build.gradle中添加apply plugin: 'kotlin-kapt'。
解决方法是在build.gradle中添加以下代码:
apply plugin: 'kotlin-kapt'
然后添加以下依赖:
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" implementation "androidx.room:room-runtime:$roomVersion" kapt "androidx.room:room-compiler:$roomVersion" implementation "androidx.paging:paging-runtime:$paging_version"
这样就能解决"Cannot create an instance of class ViewModel kotlin"的问题了。
在使用ViewModel的过程中,可能会遇到"Cannot create an instance of class ViewModel kotlin"的错误。这个问题的出现原因可能有两个方面:一是在实例化ViewModel时传递的参数不正确,二是在使用ViewModel时没有正确初始化。
解决这个问题的方法如下:
1. 将实例化ViewModel的代码从viewModel = ViewModelProviders.of(activity!!).get(BookmarkViewModel::class.java)
改为viewModel = ViewModelProviders.of(this).get(BookmarkViewModel::class.java)
。这样可以确保ViewModel是在Fragment中实例化的。
2. 将实例化的ViewModel声明为lateinit var
,这样就不需要立即初始化,但是需要在访问之前进行初始化。可以使用private lateinit var viewModel: BookMarkViewModel
来声明ViewModel。
3. 如果ViewModel的创建依赖于Room库,需要确保Room库的依赖版本一致,并且使用kapt
替代annotationProcessor
。在dependencies中添加apply plugin: 'kotlin-kapt'
。
4. 如果以上方法都没有解决问题,可能是数据库的创建代码出现了错误。可以提供数据库创建代码以供检查。
以上是解决"Cannot create an instance of class ViewModel kotlin"问题的方法。最近版本的Android Studio中,使用ViewModel时需要注意使用ViewModelProvider
代替ViewModelProviders
,并且注意使用正确的构造函数。