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 устарел.

Чтобы избежать использования устаревших библиотек, внесите следующие изменения:

  1. В файле 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, поэтому вам не нужно указывать оба в зависимостях.

  2. В разделе 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" }
    }
    
  3. В вашем фрагменте или действии измените импорт на:

    импортировать androidx.activity.viewModels

  4. Код для создания 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() устарел.

Используйте конструкторы ViewModelProvider напрямую, поскольку они теперь обрабатывают роль ViewModelProvider.Factory по умолчанию.

 mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);

Вероятно, вы можете просто использовать:

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