Невозможно создать экземпляр класса ViewModel kotlin

Вот мой код

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

Это из образцов 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: Cannot create an instance of class com.lacas.db.room.BookmarkViewModel

Могу я использовать это во фрагменте?

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lacas.asd/com.lacas.asd.ui.activities.testtabs.TestTab2Activity}: java.lang.RuntimeException: Cannot create an instance of class 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: Cannot create an instance of class 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)  Caused by: java.lang.RuntimeException: cannot find implementation for com.lacas.asd.db.room.BookmarkDb. BookmarkDb_Impl does not exist at android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:93) at android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:630) at com.lacas.asd.db.room.BookmarkDb$Companion.get(BookmarkDb.kt:29) at com.lacas.asd.db.room.BookmarkViewModel.(BookmarkViewModel.kt:14) 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) 

java.lang.RuntimeException: cannot find implementation for com.lacas.asd.db.room.BookmarkDb. BookmarkDb_Impl
denvercoder9 23.05.2018 13:07
8
1
12 820
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Сменить 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

РЕДАКТИРОВАТЬ Корень проблемы заключался в том, что Room Dependencies, где либо использовался другой вариант, либо annotationProcessor, вместо kapt (kapt требуется при использовании Kotlin)

Пробовал с этим и lateinit, то же самое ... Также пробовал с: private val viewModel от lazy (LazyThreadSafetyMode.NONE) {ViewModelProviders.of (this) .get (CheeseViewModel :: class.java)}, но всегда то же самое ...

lacas 23.05.2018 12:20

Я использую вкладки и фрагменты .. И мне нужен экземпляр в последнем фрагменте / вкладке. Является ли это возможным? Или просто в действии?

lacas 23.05.2018 12:22

Да, вы можете создать экземпляр ViewModel в Fragment. Обычно ViewModels можно использовать внутри UIControllers. Почему вы используете AndroidViewModel, а не только ViewModel? Есть ли за этим какая-то причина? И этот FirstFragment() просто базовый Fragment?

Rene Ferrari 23.05.2018 12:24

Да, FirstFragment - это абстрактный фрагмент с некоторыми абстрактными методами. Я просто скопировал код "образца страницы" из образцов Google. :) Но это работает в этом проекте, но в действии. Как обновить этот код для работы с ViewModel вместо AndroidViewModel?

lacas 23.05.2018 12:32

Я только что сделал базовый проект с кодом, похожим на ваш (AndroidViewModel +, как вы его инстанциируете). У меня все работало нормально. Не могли бы вы опубликовать весь Stacktrace (отредактируйте свой ответ или разместите его как комментарий: 3)? Я считаю, что ошибка должна быть где-то еще ... Ой, извините, придерживайтесь AndroidViewModel, так как вам нужна ссылка на Context :)

Rene Ferrari 23.05.2018 12:38

U используется в tabStrip? фрагментарно?

lacas 23.05.2018 12:52

Нет, я не использовал вкладки, но я не считаю, что это должно иметь значение, поскольку вкладка все еще содержит фрагмент;)

Rene Ferrari 23.05.2018 12:54

Хорошо, похоже, ваш Database вызывает проблему. Caused by: java.lang.RuntimeException: cannot find implementation for com.lacas.asd.db.room.BookmarkDb. BookmarkDb_Impl does not exist

Rene Ferrari 23.05.2018 13:17

Поскольку вы работаете с Kotlin. В ваших зависимостях для Room вы используете kapt вместо annotationProcessor, и все ли ваши зависимости для Room имеют одинаковую версию? Если нет, измените это и повторите попытку. Если он по-прежнему не работает, я был бы очень рад, если бы вы предоставили мне свой код для создания базы данных, поскольку ошибка, вероятно, будет где-то там.

Rene Ferrari 23.05.2018 13:20

Спасибо, наконец-то работает ... Я только что выдернула волосы из этой сессии: D

lacas 23.05.2018 13:25

Да :) Мне жаль, что это было так сложно понять, но рад, что теперь это работает :)!

Rene Ferrari 23.05.2018 13:32

В самых последних версиях Android Studio добавление kapt приводит к ошибке: «Причина: приложение: исходный kapt устарел». поэтому вам нужно добавить apply plugin: 'kotlin-kapt' в свой build.gradle.

Rosário Pereira Fernandes 25.06.2018 00:26
Ответ принят как подходящий

Как кто-то сказал здесь:

Постоянная комната Android: AppDatabase_Impl не существует

решение было:

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.

Rosário Pereira Fernandes 25.06.2018 00:26

удалить kapt "xxxx.xxx." если вы все еще используете это в своем gradle.build, так как он устарел, и добавьте

apply plugin: 'kotlin-kapt'

в конце вашего gradle.build для модуля приложения. это устранило мою проблему в Android Studio 3.1

У меня сработали 3 вещи:

  1. Добавление / сохранение как 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"

  1. Добавление apply plugin: 'kotlin-kapt' вверху build.gradle (app) и очистка проекта

  2. Повторная установка приложения

В моем случае я забыл аннотировать свой класс DatabaseClass с помощью

@Database(entities = [Book::class], version = 1)
abstract class BookRoomDatabase: RoomDatabase() 

в моем случае мне добавили private set в DatabaseClass: | Я удалил это.

  private var INSTANCE: NoteDatabase? = null
            private set

к :

private var INSTANCE: NoteDatabase? = null

эта проблема занимает у меня 2 часа: |||

при создании экземпляра модели просмотра ему просто нужен параметр приложения в суперконструкторе

Jetwiz 25.01.2020 08:05

В моем случае эта реализация решила мою проблему

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"

до того, как я реализовал это только implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

Другие вопросы по теме