Вот мой код
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)
Сменить 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)}, но всегда то же самое ...
Я использую вкладки и фрагменты .. И мне нужен экземпляр в последнем фрагменте / вкладке. Является ли это возможным? Или просто в действии?
Да, вы можете создать экземпляр ViewModel в Fragment. Обычно ViewModels можно использовать внутри UIControllers. Почему вы используете AndroidViewModel, а не только ViewModel? Есть ли за этим какая-то причина? И этот FirstFragment() просто базовый Fragment?
Да, FirstFragment - это абстрактный фрагмент с некоторыми абстрактными методами. Я просто скопировал код "образца страницы" из образцов Google. :) Но это работает в этом проекте, но в действии. Как обновить этот код для работы с ViewModel вместо AndroidViewModel?
Я только что сделал базовый проект с кодом, похожим на ваш (AndroidViewModel +, как вы его инстанциируете). У меня все работало нормально. Не могли бы вы опубликовать весь Stacktrace (отредактируйте свой ответ или разместите его как комментарий: 3)? Я считаю, что ошибка должна быть где-то еще ... Ой, извините, придерживайтесь AndroidViewModel, так как вам нужна ссылка на Context :)
U используется в tabStrip? фрагментарно?
Нет, я не использовал вкладки, но я не считаю, что это должно иметь значение, поскольку вкладка все еще содержит фрагмент;)
Хорошо, похоже, ваш Database вызывает проблему. Caused by: java.lang.RuntimeException: cannot find implementation for com.lacas.asd.db.room.BookmarkDb. BookmarkDb_Impl does not exist
Поскольку вы работаете с Kotlin. В ваших зависимостях для Room вы используете kapt вместо annotationProcessor, и все ли ваши зависимости для Room имеют одинаковую версию? Если нет, измените это и повторите попытку. Если он по-прежнему не работает, я был бы очень рад, если бы вы предоставили мне свой код для создания базы данных, поскольку ошибка, вероятно, будет где-то там.
Спасибо, наконец-то работает ... Я только что выдернула волосы из этой сессии: D
Да :) Мне жаль, что это было так сложно понять, но рад, что теперь это работает :)!
В самых последних версиях Android Studio добавление kapt приводит к ошибке: «Причина: приложение: исходный kapt устарел». поэтому вам нужно добавить apply plugin: 'kotlin-kapt' в свой build.gradle.
Как кто-то сказал здесь:
Постоянная комната 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.
удалить kapt "xxxx.xxx." если вы все еще используете это в своем gradle.build, так как он устарел, и добавьте
apply plugin: 'kotlin-kapt'
в конце вашего gradle.build для модуля приложения. это устранило мою проблему в Android Studio 3.1
У меня сработали 3 вещи:
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"
Добавление apply plugin: 'kotlin-kapt' вверху build.gradle (app) и очистка проекта
Повторная установка приложения
В моем случае я забыл аннотировать свой класс 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 часа: |||
при создании экземпляра модели просмотра ему просто нужен параметр приложения в суперконструкторе
В моем случае эта реализация решила мою проблему
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
до того, как я реализовал это только
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
java.lang.RuntimeException: cannot find implementation for com.lacas.asd.db.room.BookmarkDb. BookmarkDb_Impl