Глядя на Гугл документы для ViewModel, они показывают приведенный ниже пример кода о том, как получить ViewModel:
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
При использовании последней зависимости android.arch.lifecycle:extensions:1.1.1 такого класса ViewModelProviders нет.
Перейдя к документация для ViewModelProviders, я увидел комментарий, в котором говорилось:
This class was deprecated in API level 1.1.0. Use ViewModelProvider.AndroidViewModelFactory
Проблема в том, что при попытке использовать ViewModelProvider.AndroidViewModelFactory не удается найти эквивалентный метод of для получения экземпляра ViewModel.
Что я пытался сделать:
ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)
Отсюда и название метода create, я получаю новый экземпляр ViewModel каждый раз, когда вызываю его, а это не то, что мне нужно.
Есть идеи, что такое замена устаревшего кода выше?
это должно работать так
viewModel = ViewModelProviders.of(this@MainActivity).get(MainActivityViewModel::class.java)
В то время как ваш код будет экземпляром класса, он не будет создавать соединение с состоянием представления, которое требуется для того, чтобы класс модели представления правильно реагировал на события жизненного цикла. Вам необходимо правильно создать экземпляры View Models, чтобы они реагировали и соблюдали жизненные циклы своих родителей, иначе они каждый раз воссоздались свежими и пустыми.
Как отмечалось выше ОП и другими; класс ViewModelProviders устарел. См .: developer.android.com/reference/androidx/lifecycle/…
ОБНОВЛЕНИЕ 2020-06-16: В настоящее времяViewModelProviders устарел и больше не должен использоваться. Этот вопрос и ответ были заданы в конце 2018 года, когда это было не так. Этот вопрос и ответ также относятся к более старой версии компонентов архитектуры ViewModelProviders, а не к версии AndroidX.
When using the latest dependency
android.arch.lifecycle:extensions:1.1.1there is no such classViewModelProviders.
Да, есть. Чтобы продемонстрировать это:
Создайте новый проект в 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)
}
}
Going to the documentation for ViewModelProviders, I saw a comment saying: This class was deprecated in API level 1.1.0. Use ViewModelProvider.AndroidViewModelFactory
Этот комментарий находится под записью класса ViewModelProviders.DefaultFactory и относится к этому классу, а не к ViewModelProviders:

Any ideas what is the replacement of deprecated code above?
Используйте ViewModelProviders.
@TareKKhoury: Это все объяснит! Определенно может быть непросто отследить, какие модули и какие зависимости нужны. Рад слышать, что у вас все заработало!
Это уже не так, ViewModelProviders.of() больше не существует.
Да @Tarek, он устарел. Используйте сейчас с AndroidX:
val yourViewModel = ViewModelProvider.NewInstanceFactory().create(YourVideoModel::class.java)
Это неверный ответ. Вы должны использовать ViewModelProvider(viewModelStoreOwner, factory).get(YourVideoModel::class.java), иначе ваш onCleared() не будет работать правильно, и ViewModel не будет сохраняться при изменении конфигурации. Не используйте этот ответ.
Вероятно, вы можете просто использовать:
val viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)
без необходимости добавлять android.arch.lifecycle:extensions:1.1.1 в качестве зависимости.
Я использую версию 2.2.0 с расширениями жизненного цикла:
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
Он должен работать, используя конструктор ViewModelProvider.
// With ViewModelFactory
val viewModel = ViewModelProvider(this, YourViewModelFactory).get(YourViewModel::class.java)
//Without ViewModelFactory
val viewModel = ViewModelProvider(this).get(YourViewModel::class.java)
2020/5/15 Обновление
Я нашел еще один элегантный способ добиться этого, Android KTX может помочь
implementation "androidx.fragment:fragment-ktx:1.2.4"
val viewmodel: MYViewModel by viewModels()
val viewmodel: MYViewModel by viewModels { myFactory } //With factory
Ссылка: https://developer.android.com/reference/kotlin/androidx/fragment/app/package-summary#viewmodels
25.06.2020: исправлен случай делегата
Меня как бы тошнит от постоянного цикла "обесценивания" со стороны Google.
ViewModelProviders.of () устарел. Вы можете передать Fragment или FragmentActivity новому конструктору ViewModelProvider (ViewModelStoreOwner) для достижения той же функциональности. (AOSP / 1009889)
Эквивалент Java: YourViewModel viewModel = new ViewModelProvider(this).get(YourViewModel.class);
Я беспокоюсь, если когда-нибудь Google откажется от поддержки TextView или EditText и представит новый компонент.
androidx lifecycle-viewmodel 2.1.0 не имеет конструктора без фабрики. использование просто (это) не работает. ViewModelProvider (ViewModelStoreOwner, Factory) и ViewModelProvider (ViewModelStore, Factory) - единственные конструкторы.
Есть ли причина для изменения?
По мере развития программного обеспечения старые реализации устаревают. Это естественно, с этим бороться бесполезно.
@AFD правда. Некоторые библиотеки Google меняют API каждый месяц, например WebRTC android. Очень неприятно изучать фреймворк из руководств
Значит, нам нужно каждый раз создавать новые объекты?
Как отметил @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);
Или, если вы не используете фабрику, просто используйте:
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
Без передачи вашего фабричного объекта.
Вы должны использовать следующее в build.gradle: implementation "androidx.lifecycle: lifecycle-viewmodel: $ lifecycle_version" Как отмечено в developer.android.com/jetpack/androidx/releases/lifecycle. API в расширениях жизненного цикла устарели. Вместо этого добавьте зависимости для конкретных артефактов жизненного цикла, которые вам нужны.
Используйте ViewModelProvider напрямую вместо пользователя ViewModelProviders.of (), как указано в документации.
ViewModelProvider(this).get(XViewModel::class.java)
https://developer.android.com/reference/androidx/lifecycle/ViewModelProviders
Если вы используете Kotlin, вы можете использовать делегат свойства viewModels() следующим образом:
val viewModel: YourViewModel by viewModels()
Источник: https://forums.bignerdranch.com/t/solution-to-deprecated-method-viewmodelproviders-of/16833
Я использую 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)
спасибо за ваш ответ, но когда я использую его, тогда просмотр модели просмотра и привязка данных к полям больше не работают
Я считаю, что androidx.lifecycle:lifecycle-compiler устарел androidx.lifecycle:lifecycle-common-java8.
Если у вас есть эта реализация
'implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
Попробуй использовать
viewModel = MainViewModel()
Это не способ создать экземпляр модели представления. Для этого вы должны использовать класс ViewModelProvider
По состоянию на 2.2.0. расширения жизненного цикла устарели. Обратитесь к Документация Google.
Это вырезка со страницы:
The APIs in lifecycle-extensions have been deprecated. Instead, add dependencies for the specific Lifecycle artifacts you need.
Новые библиотеки:
// 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)
Сохраняем ли мы isntsance ViewModelProvider или должны воссоздавать его снова, и в этом случае все базовые экземпляры также будут уничтожены. Я не являюсь причиной его воссоздания, если идея состоит в том, чтобы наблюдать за жизненным циклом фрагмента / активности.
Спасибо за включение Java - некоторым из нас все еще приходится поддерживать устаревший код.
Я не эксперт, но у меня есть строка кода, которая решила мою проблему на Java. Надеюсь, это кому-то поможет.
viewModel =
new ViewModelProvider
.AndroidViewModelFactory(getApplication())
.create(ViewModel.class);
Как я уже сказал, я хотел бы предоставить более подробную информацию, но это устранило эту проблему для меня.
Этот код неверен, onCleared() не будет называться таким образом, и ваша ViewModel будет воссоздаваться каждый раз (не сохраняется для изменений конфигурации).
Не могли бы вы объяснить немного подробнее на конкретном примере, что бы исправить мою ошибку? Пожалуйста, вставьте ссылку на объяснение или что-нибудь, что могло бы прояснить ситуацию
viewModel = new ViewModelProvider(this).get(MyViewModel.class). Если ваш AndroidViewModel не получает Application, значит у вас есть несоответствие версий между жизненным циклом и действием / фрагментом.
Хорошо, значит, вызов getApplicationContext неверен? Должен ли это быть просто getContext?
Проблема заключается в создании new ViewModelProvider.AndroidViewModelFactory( вместо new ViewModelProvider(.
Попробуй это...
LocationViewModel locationViewModel = new ViewModelProvider(this).get(LocationViewModel.class);
Устарело с:
import androidx.lifecycle.ViewModelProviders;К:
import androidx.lifecycle.ViewModelProvider;
Устарело с:
ViewModelProviders.of(this, provider).get(VM::class.java)К:
ViewModelProvider(this, provider).get(VM::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().
Собственно, что делает метод 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);
Если вы реализуете Factory, у вас есть другой способ: у ViewModelProvider есть конструктор, который ожидает как ViewModelStoreOwner, так и Factory.
Вместо этого вы можете использовать это:
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);
Потому что, когда я использовал этот способ, я получил сообщение об ошибке ниже:
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.canerkaseler.mvvmexample.ViewModel
Это неверный ответ. Вам необходимо передать фабрику ViewModelProvider. Если вы вызываете create напрямую, то onCleared() не будет работать правильно.
Фактически, вы буквально только что сказали не использовать правильный ответ. Похоже, у вас есть несоответствие между вашими зависимостями androidx.core и androidx.lifecycle.
Обычно я записывал фабрику в ViewModelProvider. Однако вы его удалили. ContactViewModel contactViewModel = новый ViewModelProvider.AndroidViewModelFactory (getApplication ()). create (ContactViewMo del.class); Почему вы удалили его в моем ответе? Вы ввели неправильные коды.
Когда вы используете кинжал, вы передаете factory в конструкторе
MobileViewModel mobileViewModel = new ViewModelProvider(this,providerFactory).get(MobileViewModel.class);
Использовать это:
YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);
не будет ли это создавать новый экземпляр каждый раз, когда вызывается create? Предположим, такой жизненный цикл, стоп, onCreate?
Если вы смотрите видео с Udacity, где вы создаете GameViewModel и не хотите писать устаревший код, просто замените:
viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)
со следующим кодом:
viewModel = ViewModelProvider(this).get(GameViewModel::class.java)
и вернуться к чтению как можно скорее !!
Я продолжал пробовать и закончил с этим решением в 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, чтобы проверить текущую версию.
Я столкнулся с той же проблемой. если что-то не работает, попробуйте этот фрагмент кода в своем oncreate и отредактируйте его в соответствии с вашим файлом и бум, вы gtg
val model = ViewModelProvider(viewModelStore,ViewModelProvider.AndroidViewModelFactory.getInstance(application)).get(MainActivityViewModel::class.java)
// вам просто нужно изменить класс модели
Прочтите Как ответить и обновите свой вопрос.
Пользуюсь фабрикой.
ViewModelProvider.AndroidViewModelFactory
.getInstance(getApplication())
.create(DashboardViewModel.class);
Просто обновите с
ViewModelProviders.of(this, provider).get(MainActivityViewModel::class.java)
к
ViewModelProvider(this, provider).get(MainActivityViewModel::class.java)
Вы можете использовать что-то вроде этого:
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.
Я использую библиотеку жизненного цикла 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 () в своем коде Котлин, как показано ниже:
import androidx.fragment.app.viewModels
private val cartViewModel: CartViewModel by viewModels()
использовать одноэлементный шаблон или перейти на AndroidX