ViewModelProviders устарела в 1.1.0
Глядя на документы Google для ViewModel
они показывают приведенный ниже пример кода о том, как получить ViewModel
:
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
При использовании последней зависимости android.arch.lifecycle:extensions:1.1.1
такого класса нет ViewModelProviders
,
Переход к документации для ViewModelProviders
Я увидел комментарий:
Этот класс устарел на уровне API 1.1.0. Используйте ViewModelProvider.AndroidViewModelFactory
Проблема в том, что при попытке использовать ViewModelProvider.AndroidViewModelFactory
не может найти эквивалент of
метод, чтобы получить экземпляр ViewModel
,
Что я пытался сделать:
ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)
Отсюда и название метода create
Я получаю новый экземпляр ViewModel каждый раз, когда я его называю, но это не то, что мне нужно.
Любые идеи, что замена устаревшего кода выше?
32 ответа
При использовании последней зависимости
android.arch.lifecycle:extensions:1.1.1
такого класса нетViewModelProviders
,
Да, есть. Чтобы продемонстрировать это:
Создайте новый проект в Android Studio 3.2.1 (с Kotlin,
minSdkVersion
21, шаблон "пустая активность")добавлять
android.arch.lifecycle:extensions:1.1.1
к зависимостямapp
модуль
Это даст вам app/build.gradle
лайк:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.commonsware.myandroidarch"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'android.arch.lifecycle:extensions:1.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
Затем вы увидите, что библиотека отображается во "Внешних библиотеках" с этим классом:
И вы сможете сослаться на этот класс:
package com.commonsware.myandroidarch
import android.arch.lifecycle.ViewModelProviders
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val provider = ViewModelProviders.of(this)
}
}
Переходя к документации для ViewModelProviders, я увидел комментарий, говорящий: этот класс устарел на уровне API 1.1.0. Используйте ViewModelProvider.AndroidViewModelFactory
Этот комментарий находится под ViewModelProviders.DefaultFactory
запись класса и относится к этому классу, а не ViewModelProviders
:
Любые идеи, что замена устаревшего кода выше?
использование ViewModelProviders
,
I use lifecycle-extensions 2.2.0-alpha03
версия:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha03'
It should be work, using ViewModelProvider
конструктор.
// With ViewModelFactory
val viewModel = ViewModelProvider(this, YourViewModelFactory).get(YourViewModel::class.java)
//Without ViewModelFactory
val viewModel = ViewModelProvider(this).get(YourViewModel::class.java)
Как упомянул @FantasyFang в своем ответе, используйте самую последнюю версию для lifecycle:lifecycle-extensions
который в данный момент 2.2.0-alpha03
, Поэтому вы должны добавить в свой файл build.gradle следующую строку:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha03'
Для тех, кто использует Java, чтобы решить эту проблему, передайте эти аргументы непосредственно конструктору ViewModelProvider:
MyViewModel viewModel = new ViewModelProvider(this, myViewModelFactory).get(MyViewModel::class.java);
Или, если вы не используете фабрику, просто используйте:
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel::class.java);
Не передавая ваш заводской объект.
Устарело с: ViewModelProviders.of(this, provider).get(VM::class.java)
Кому: ViewModelProvider(this, provider).get(VM::class.java)
По состоянию на 2.2.0. расширения жизненного цикла устарели. Обратитесь к документации Google.
Это вырезка со страницы:
API-интерфейсы в расширениях жизненного цикла устарели. Вместо этого добавьте зависимости для конкретных артефактов жизненного цикла, которые вам нужны.
Новые библиотеки:
// ViewModel and lifecycle support for java
implementation "androidx.lifecycle:lifecycle-viewmodel:${versions.lifecycle}"
implementation "androidx.lifecycle:lifecycle-livedata:${versions.lifecycle}"
// ViewModel and lifecycle support for kotlin
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.lifecycle}"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.lifecycle}"
Новый код для JAVA:
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
Или для Котлина:
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
В начале 2020 года Google исключил класс ViewModelProviders в версии 2.2.0 библиотеки жизненного цикла androidx.
Больше нет необходимости использовать ViewModelProviders для создания экземпляра ViewModel, вместо этого вы можете передать свой фрагмент или экземпляр Activity в конструктор ViewModelProvider.
Если вы используете такой код:
val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)
вы получите предупреждение о том, что ViewModelProviders устарел.
Чтобы избежать использования устаревших библиотек, внесите следующие изменения:
В файле build.gradle (Module: app) используйте версию 2.2.0 компонентов жизненного цикла:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation "androidx.activity:activity-ktx:1.1.0"
Если вы хотите вместо этого использовать ViewModel из фрагмента, используйте
implementation "androidx.fragment:fragment-ktx:1.2.2"
fragment-ktx автоматически включает activity-ktx, поэтому вам не нужно указывать оба в зависимостях.
В разделе android нужно указать Java 8:
android { compileSdkVersion 28 defaultConfig { applicationId "com.kgandroid.calculator" minSdkVersion 17 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } kotlinOptions { jvmTarget = "1.8" } }
В вашем фрагменте или действии измените импорт на:
импортировать androidx.activity.viewModels
Код для создания ViewModel становится таким:
val viewModel: CalculatorViewModel by viewModels()
вместо того
val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)
Используйте объект viewModel как:
val viewModel: CalculatorViewModel by viewModels() viewModel.newNumber.observe(this, Observer<String> { stringResult -> newNumber.setText(stringResult) })
где newNumer - объект LiveData
Во фрагменте, которым вы хотите поделиться ViewModel Activity, вы должны использовать
val viewModel: CalculatorViewModel by activityViewModels()
Это эквивалент передачи экземпляра Activity в (устаревшем) ViewModelProviders.of()
функция.
Вероятно, вы можете просто использовать:
val viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)
без необходимости добавлять android.arch.lifecycle:extensions:1.1.1
как зависимость.
Собственно, при чем тут ViewModelProviders.of()
способ делать под капотом?
@Deprecated
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
return new ViewModelProvider(fragment);
}
Занимает Fragment
в качестве аргумента создает ViewModelProvider
объект и передает фрагмент прямо в ViewModelProvider
конструктор.
Мы можем использовать то же самое.
Например, до:
OurViewModel mOurViewModel = ViewModelProviders.of(this).get(OurViewModel.class);
После:
OurViewModel mOurViewModel = new ViewModelProvider(this).get(OurViewModel.class);
Если вы смотрите видео с
Udacity
где вы создаете
GameViewModel
и вы не хотите писать устаревший код, просто замените:
viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)
со следующим кодом:
viewModel = ViewModelProvider(this).get(GameViewModel::class.java)
и вернуться к чтению как можно скорее!!
Да, @Tarek, это устарело. Используйте сейчас с AndroidX:
val yourViewModel = ViewModelProvider.NewInstanceFactory().create(YourVideoModel::class.java)
Используйте ViewModelProvider напрямую вместо пользователя ViewModelProviders.of(), как указано в документации.
ViewModelProvider(this).get(XViewModel::class.java)
https://developer.android.com/reference/androidx/lifecycle/ViewModelProviders
Я использую android X
а также имел эту проблему.
Прежде всего, вы должны добавить эти зависимости в свойGradle
:
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
В моем случае $lifecycle_version был 2.2.0-rc02
Во-вторых: импорт дляViewModelProvider
должно быть:
import androidx.lifecycle.ViewModelProvider
Затем вы можете инициализировать vIewModel, как в примерах ниже:
val viewModel = ViewModelProvider(this, YourFactoryInstace).get(MainViewModel::class.java)
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
Если вы используете Kotlin, вы можете использовать делегат свойства viewModels()
нравится:
val viewModel: YourViewModel by viewModels()
Источник: https://forums.bignerdranch.com/t/solution-to-deprecated-method-viewmodelproviders-of/16833
Использовать это:
YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
Вместо этого вы можете использовать это:
viewModel= ViewModelProvider(this).get(YourViewModel::class.java)
"this" в скобках - владелец экземпляра YourViewModel.
Это ответ для Java, но вы можете понять суть. Решение состоит в том, что вам нужно использовать ViewModelProvider, потому что ViewModelProviders устарел:
//Do not forget import it.
import androidx.lifecycle.AndroidViewModel;
ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
Пример использования:
YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
Кроме того, не забудьте обновить зависимости Gradle: проверьте здесь их последние версии
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'
!!! Однако будьте осторожны, потому что некоторые ответы рекомендуют это решение, но оно не сработало для меня:
yourViewModel = new ViewModelProvider(this).get(YourViewModel.class);
Потому что, когда я использовал этот способ, я получил сообщение об ошибке ниже:
Вызвано: java.lang.RuntimeException: невозможно создать экземпляр класса com.canerkaseler.mvvmexample.ViewModel
@canerkaseler
Обновление: 20 июля 2022 г.
частная привязка поздней версии: FragmentHomeBinding частная поздняя переменная var homeMvvM: HomeViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeMvvM = ViewModelProvider(this)[HomeViewModel::class.java]
это работает для меня.
Я не эксперт, но у меня есть строка кода, которая решила мою проблему на Java. Надеюсь, это кому-то поможет.
viewModel =
new ViewModelProvider
.AndroidViewModelFactory(getApplication())
.create(ViewModel.class);
Как я уже сказал, я хотел бы предоставить более подробную информацию, но это устранило эту проблему для меня.
Я продолжал пробовать и закончил с этим решением в Kotlin, вы тоже сможете попробовать его в java.
MainActivity.kt
val provider : ViewModelProvider = ViewModelProvider(this)
val VM = provider.get(ViewModelClass::class.java)
build.gradle
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0"
Текущая версия библиотек жизненного цикла - 2.3.0 по состоянию на 02.02.2021 г. См. Https://developer.android.com/jetpack/androidx/releases/lifecycle, чтобы проверить текущую версию.
Пользуюсь фабрикой.
ViewModelProvider.AndroidViewModelFactory
.getInstance(getApplication())
.create(DashboardViewModel.class);
Когда вы используете кинжал, вы передадите factory в конструкторе
MobileViewModel mobileViewModel = new ViewModelProvider(this,providerFactory).get(MobileViewModel.class);
//Activity ktx
implementation 'androidx.activity:activity-ktx:1.5.1'
//Fragment ktx
implementation 'androidx.fragment:fragment-ktx:1.5.1'
Самый простой способ создания моделей просмотра:
class MyViewModel() : ViewModel() {
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_some)
}
}
Просмотр модели с аргументами конструктора:
class MyViewModel(list:List<String>) : ViewModel() {
class Factory(list:List<String>) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return MyViewModel(list) as T
}
}
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels(){
MyViewModel.Factory(listOf<String>("a"))}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Просто обновите с
ViewModelProviders.of (этот, провайдер) .get(MainActivityViewModel :: class.java)
к
ViewModelProvider (это, поставщик) .get(MainActivityViewModel :: class.java)
Попробуйте добавить этот код на уровень модуля build.gradle.
android {
kotlinOptions {
freeCompilerArgs += [
'-Xjvm-default=enable'
]
}
}
Там нет ничего о get
метод, который deprecated
, Если вы будете следовать инструкциям разработчика Android, вы должны получить VM
как это.
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
}
}
Вот инструкция о том, как использовать ViewModels
Вот инструкции о том, как настроить ваш проект с правильными зависимостями
Я столкнулся с той же проблемой. если что-то не работает, попробуйте этот кусок кода в свой oncreate и отредактируйте его в соответствии с вашим файлом, и вы - gtg
val model = ViewModelProvider (viewModelStore, ViewModelProvider.AndroidViewModelFactory.getInstance (application)). get (MainActivityViewModel :: class.java) // вам просто нужно изменить класс модели
Я использую библиотеку жизненного цикла 2.3.1 и добавляю ниже зависимость в build.gradle (уровень модуля)
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-extensions-ktx:2.2.0'
implementation 'androidx.activity:activity-ktx:1.4.0'
implementation 'androidx.fragment:fragment-ktx:1.3.6'
Объявите viewModels() в коде Kotlin , как показано ниже:
import androidx.fragment.app.viewModels
private val cartViewModel: CartViewModel by viewModels()
Вы можете использовать что-то вроде этого:
private val sharedViewModel: SharedViewModel by viewModels(ownerProducer = { requireActivity() })
ownerProducer = { requireActivity() } // This is only required if you want to share same view model among different fragments.
Попробуй это...
LocationViewModel locationViewModel = new ViewModelProvider(this).get(LocationViewModel.class);