无法创建类 ViewModel kotlin 的实例
Posted
技术标签:
【中文标题】无法创建类 ViewModel kotlin 的实例【英文标题】:Cannot create an instance of class ViewModel kotlin 【发布时间】:2018-11-02 06:19:56 【问题描述】:这是我的代码
class BookmarkViewModel(app: Application) : androidViewModel(app)
private val dao = BookmarkDb.get(app).bookmarkDao()
companion object
private const val PAGE_SIZE = PagingConstants.PERPAGE
/**
* If placeholders are enabled, PagedList will report the full size but some items might
* be null in onBind method (PagedListAdapter triggers a rebind when data is loaded).
* <p>
* If placeholders are disabled, onBind will never receive null but as more pages are
* loaded, the scrollbars will jitter as new pages are loaded. You should probably disable
* scrollbars if you disable placeholders.
*/
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)
这是来自谷歌样本.. 在我想要之后:
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 类的实例
我可以在片段中使用它吗?
java.lang.RuntimeException:无法启动活动 ComponentInfocom.lacas.asd/com.lacas.asd.ui.activities.testtabs.TestTab2Activity:java.lang.RuntimeException:无法创建 com 类的实例。 lacas.asd.db.room.BookmarkViewModel 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2924) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985) 在 android.app.ActivityThread.-wrap14(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6692) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 原因:java.lang.RuntimeException:无法创建类 com.lacas.asd.db.room.BookmarkViewModel 的实例 在 android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:207) 在 android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134) 在 android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:34) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:29) 在 kotlin.UnsafeLazyImpl.getValue(Lazy.kt:154) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity.getViewModel(TestTab2Activity.kt) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity.onCreated(TestTab2Activity.kt:45) 在 com.lacas.asd.base.BasePermissionsActivity.onCreate(BasePermissionsActivity.kt:34) 在 android.app.Activity.performCreate(Activity.java:6912) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2877) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985) 在 android.app.ActivityThread.-wrap14(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6692) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 引起:java.lang.reflect.InvocationTargetException 在 java.lang.reflect.Constructor.newInstance0(本机方法) 在 java.lang.reflect.Constructor.newInstance(Constructor.java:430) 在 android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:199) 在 android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134) 在 android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:34) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:29) 在 kotlin.UnsafeLazyImpl.getValue(Lazy.kt:154) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity.getViewModel(TestTab2Activity.kt) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity.onCreated(TestTab2Activity.kt:45) 在 com.lacas.asd.base.BasePermissionsActivity.onCreate(BasePermissionsActivity.kt:34) 在 android.app.Activity.performCreate(Activity.java:6912) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2877) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985) 在 android.app.ActivityThread.-wrap14(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6692) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 原因:java.lang.RuntimeException:找不到 com.lacas.asd.db.room.BookmarkDb 的实现。 BookmarkDb_Impl 不存在 在 android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:93) 在 android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:630) 在 com.lacas.asd.db.room.BookmarkDb$Companion.get(BookmarkDb.kt:29) 在 com.lacas.asd.db.room.BookmarkViewModel.(BookmarkViewModel.kt:14) 在 java.lang.reflect.Constructor.newInstance0(本机方法) 在 java.lang.reflect.Constructor.newInstance(Constructor.java:430) 在 android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:199) 在 android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134) 在 android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:34) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity$viewModel$2.invoke(TestTab2Activity.kt:29) 在 kotlin.UnsafeLazyImpl.getValue(Lazy.kt:154) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity.getViewModel(TestTab2Activity.kt) 在 com.lacas.asd.ui.activities.testtabs.TestTab2Activity.onCreated(TestTab2Activity.kt:45) 在 com.lacas.asd.base.BasePermissionsActivity.onCreate(BasePermissionsActivity.kt:34) 在 android.app.Activity.performCreate(Activity.java:6912) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2877) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985) 在 android.app.ActivityThread.-wrap14(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6692) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
【问题讨论】:
java.lang.RuntimeException: cannot find implementation for com.lacas.asd.db.room.BookmarkDb. BookmarkDb_Impl
【参考方案1】:
这里有人说:
Android room persistent: AppDatabase_Impl does not exist
解决办法是:
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"
【讨论】:
在最新版本的 Android Studio 中,添加kapt
会导致构建错误:“原因:应用程序:不推荐使用原始 kapt。”所以你需要将apply plugin: 'kotlin-kapt'
添加到你的build.gradle。【参考方案2】:
更改viewModel = ViewModelProviders.of(activity!!).get(BookmarkViewModel::class.java)
致viewModel = ViewModelProviders.of(this).get(BookmarkViewModel::class.java)
此外,不要将viewModel
实例化为null
。将其更改为 lateinit var
这样您就不必立即实例化(但您告诉 Kotlin 您将在访问它之前实例化它)。你可以这样做:private lateinit var viewModel: BookMarkViewModel
EDIT 问题的根源在于Room Dependencies
不是在同一版本上或annotationProcessor
被使用而不是kapt
(使用Kotlin 时需要kapt
)
【讨论】:
用 this 和 lateinit 试过,同样... 也试过: private val viewModel by lazy(LazyThreadSafetyMode.NONE) ViewModelProviders.of(this).get(CheeseViewModel::class.java) 但总是一样... 我正在使用选项卡和片段。我希望在最后一个片段/选项卡中有一个实例。可能吗?还是只是在活动? 因为您使用的是 Kotlin。在 Room 的依赖项中,您是否使用kapt
而不是 annotationProcessor
并且所有 Room 依赖项都具有相同的版本?如果不更改,然后重试。如果它仍然不起作用,如果你能提供我你的数据库创建代码,我会非常高兴,因为错误可能就在某个地方。
是的 :) 很抱歉,很难弄清楚,但很高兴它现在可以工作了 :)!
在最新版本的 Android Studio 中,添加 kapt
会导致错误:“原因:应用程序:不推荐使用原始 kapt。”所以你需要将apply plugin: 'kotlin-kapt'
添加到你的build.gradle。【参考方案3】:
删除 kapt “xxxx.xxx”。如果您仍然在 gradle.build 中使用它,因为它已被弃用并添加
apply plugin: 'kotlin-kapt'
在应用模块的 gradle.build 末尾。 这解决了我在 android studio 3.1 中的问题
【讨论】:
【参考方案4】:这三件事对我有用:
-
在依赖项中添加/保留 annotationProcessor 和 Kapt
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
kapt "android.arch.lifecycle:compiler:$lifecycle_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
在 build.gradle(app) 顶部添加apply plugin: 'kotlin-kapt'
并清理项目
重新安装应用程序
【讨论】:
【参考方案5】:在我的情况下,我在 DatabaseClass 中添加了private set
:|
我删除了它。
private var INSTANCE: NoteDatabase? = null
private set
到:
private var INSTANCE: NoteDatabase? = null
这个问题花了我 2 个小时 :|||
【讨论】:
实例化viewmodel时,只需要超级构造函数中的application参数【参考方案6】:就我而言,我忘记用
注释我的 DatabaseClass 类@Database(entities = [Book::class], version = 1)
abstract class BookRoomDatabase: RoomDatabase()
【讨论】:
【参考方案7】:在我的例子中,这个实现解决了我的问题
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
在我实现这个之前
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
【讨论】:
【参考方案8】:我通过这样做解决了同样的问题。
添加注释。
class AlertViewModel
@Inject
constructor(private val userRepository: AlertRepository) : ViewModel()
val getList:LiveData<List<Alert>> get() =
userRepository.getList.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user:Alert)
viewModelScope.launch
userRepository.insert(user)
到
@HiltViewModel // Added this annotation
class AlertViewModel
@Inject
constructor(private val userRepository: AlertRepository) : ViewModel()
val getList:LiveData<List<Alert>> get() =
userRepository.getList.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user:Alert)
viewModelScope.launch
userRepository.insert(user)
【讨论】:
【参考方案9】:例如,如果您使用 Dagger/Hil,Fragment 或 Activity 应该需要 @AndroidEntryPoint
【讨论】:
以上是关于无法创建类 ViewModel kotlin 的实例的主要内容,如果未能解决你的问题,请参考以下文章
无法从 ViewModelProvider 创建 ViewModel