ViewModelProviders 1.1.0'da kullanımdan kaldırıldı


152

Baktığımızda , Google docs için ViewModel, onlar almak için nasıl örnek kod aşağıda göstermek ViewModel:

val model = ViewModelProviders.of(this).get(MyViewModel::class.java)

En son bağımlılığı kullanırken android.arch.lifecycle:extensions:1.1.1böyle bir sınıf yoktur ViewModelProviders.

Gitmek belgeler için ViewModelProviders, diyordum bir yorum gördüm:

Bu sınıf, API seviyesi 1.1.0'da kullanımdan kaldırıldı. ViewModelProvider.AndroidViewModelFactory'yi kullanın

Sorun şu ki, kullanmaya çalışırken, .NET Framework örneğini almak için ViewModelProvider.AndroidViewModelFactoryeşdeğer bir ofyöntem bulamıyorum ViewModel.

Yapmaya çalıştığım şey:

ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)

Dolayısıyla yöntemin adı create, onu her çağırdığımda ViewModel'in yeni bir örneğini alıyorum, bu benim peşinde olduğum şey değil.

Yukarıdaki kullanımdan kaldırılmış kodun yerine ne konacağına dair bir fikriniz var mı?


tek ton kalıbı kullanın veya AndroidX'e geçin
Oussema Aroua

Yanıtlar:


32

GÜNCELLEME 2020-06-16 : Şu anda ViewModelProviders kullanımdan kaldırıldı ve artık kullanılmamalıdır. Bu soru ve cevap, durumun böyle olmadığı 2018'in sonlarına aittir. Bu soru ve cevap ViewModelProviders, AndroidX sürümü değil, eski Architecture Components sürümü içindir.


En son bağımlılığı kullanırken android.arch.lifecycle:extensions:1.1.1böyle bir sınıf yoktur ViewModelProviders.

Evet var. Bunu göstermek için:

  • Android Studio 3.2.1'de yeni bir proje oluşturun (Kotlin, minSdkVersion21, "boş etkinlik" şablonu ile)

  • Modülün android.arch.lifecycle:extensions:1.1.1bağımlılıklarına ekleyinapp

Bu size bir app/build.gradlebeğeni verecektir :

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

Daha sonra bu kitaplığın "Harici Kitaplıklar" da bu sınıfla birlikte göründüğünü göreceksiniz:

Harici Kitaplıklar

Ve bu sınıfa referans verebileceksiniz:

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 belgelerine giderken, şöyle bir yorum gördüm: Bu sınıf, API seviyesi 1.1.0'da kullanımdan kaldırıldı. ViewModelProvider.AndroidViewModelFactory'yi kullanın

Yani comment altında olan ViewModelProviders.DefaultFactorysınıflara ve bu sınıfta değil, ifade eder ViewModelProviders:

Belgeler Ekran Görüntüsü

Yukarıdaki kullanımdan kaldırılmış kodun yerine ne konacağına dair bir fikriniz var mı?

Kullanın ViewModelProviders.


1
@TareKKhoury: Bunu açıklar! Hangi modüllerin hangi bağımlılıklara ihtiyaç duyduğunu takip etmek kesinlikle zor olabilir. Çalıştığını duyduğuma sevindim!
CommonsWare

15
Bu artık doğru değil, ViewModelProviders.of()artık yok.
EpicPandaForce

330

Yaşam döngüsü uzantıları 2.2.0sürümünü kullanıyorum:

implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" 

ViewModelProviderYapıcı kullanarak iş olmalı .

// With ViewModelFactory   
val viewModel = ViewModelProvider(this, YourViewModelFactory).get(YourViewModel::class.java)


//Without ViewModelFactory
val viewModel = ViewModelProvider(this).get(YourViewModel::class.java)

2020/5/15 Güncellemesi

Başarmanın başka bir zarif yolunu buluyorum, Android KTX yardımcı olabilir

implementation "androidx.fragment:fragment-ktx:1.2.4"
val viewmodel: MYViewModel by viewModels()
val viewmodel: MYViewModel by viewModels { myFactory } //With factory

Referans: https://developer.android.com/reference/kotlin/androidx/fragment/app/package-summary#viewmodels

2020/06/25: delegenin durumu düzeltildi


161
Google'ın sürekli "amortisman" döngüsünden bıktım.
AFD

3
ViewModelProviders.of () kullanımdan kaldırıldı. Aynı işlevselliği elde etmek için yeni ViewModelProvider (ViewModelStoreOwner) yapıcısına bir Fragment veya FragmentActivity iletebilirsiniz. (aosp / 1009889)
Raghu Krishnan R

32
Java eşdeğeri:YourViewModel viewModel = new ViewModelProvider(this).get(YourViewModel.class);
ban-geoengineering

16
Google'ın bir gün TextViewveya bir gün kullanımdan kaldırıp EditTextyeni bir Bileşen sunacağından endişe ediyorum .
Pranjal Choladhara

4
androidx lifecycle-viewmodel 2.1.0, fabrikasız bir kurucuya sahip değildir. basitçe (bu) kullanmak işe yaramaz. ViewModelProvider (ViewModelStoreOwner, Factory) ve ViewModelProvider (ViewModelStore, Factory) tek kuruculardır
DevinM

71

@FantasyFang'ın cevabında bahsettiği gibi lifecycle:lifecycle-extensions, şu an için en son sürümü kullanın 2.2.0-alpha03. Bu nedenle, build.gradle dosyanıza aşağıdaki satırı eklemelisiniz:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha03' 

Java kullananlar için, bunu çözmek için, bu argümanları doğrudan ViewModelProvider'ın kurucusuna iletin :

MyViewModel viewModel = new ViewModelProvider(this, myViewModelFactory).get(MyViewModel.class);

Veya bir fabrika kullanmıyorsanız, şunu kullanın:

MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);

Fabrika nesnenizi geçmeden.


1
Build.gradle: uygulama "androidx.lifecycle: lifecycle-viewmodel: $ lifecycle_version" içinde aşağıdakileri kullanmanız gerekir: developer.android.com/jetpack/androidx/releases/lifecycle'da belirtildiği gibi yaşam döngüsü uzantılarındaki API'ler kullanımdan kaldırılmıştır. Bunun yerine, ihtiyaç duyduğunuz belirli Yaşam Döngüsü yapıları için bağımlılıklar ekleyin.
Kenneth Argo

42

2.2.0 itibarıyla. yaşam döngüsü uzantıları kullanımdan kaldırıldı. Google Dokümantasyonuna bakın .

Bu, sayfadan kesilmiş:

Yaşam döngüsü uzantılarındaki API'ler kullanımdan kaldırıldı. Bunun yerine, ihtiyaç duyduğunuz belirli Yaşam Döngüsü yapıları için bağımlılıklar ekleyin.

Yeni kütüphaneler:

// 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 için yeni kod:

viewModel = new ViewModelProvider(this).get(MyViewModel.class);

Veya Kotlin için:

viewModel = ViewModelProvider(this).get(MyViewModel::class.java)

ViewModelProvider isntsance'ını tutuyor muyuz yoksa yeniden oluşturmak zorunda mıyız, bu durumda, tüm temel örnekler de yok edilecektir. Fikir parçanın / aktivitenin yaşam döngüsünü
izlemekse

31

Kullanımdan Kaldırıldığı Yer: ViewModelProviders.of(this, provider).get(VM::class.java)

Kime: ViewModelProvider(this, provider).get(VM::class.java)


4
tam olarak aradığım şey.
Rahul Bali

22

Google , 2020'nin başlarında , androidx yaşam döngüsü kitaplığının 2.2.0 sürümünde ViewModelProviders sınıfını kullanımdan kaldırdı.

ViewModel örneğini oluşturmak için ViewModelProviders kullanmak artık gerekli değildir, bunun yerine Fragment veya Activity örneğinizi ViewModelProvider yapıcısına iletebilirsiniz.

Kodu şu şekilde kullanırsanız:

val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)

ViewModelProviders'ın kullanımdan kaldırıldığına dair bir uyarı alırsınız .

Kullanımdan kaldırılmış kitaplıkları kullanmaktan kaçınmak için aşağıdaki değişiklikleri yapın:

  1. Build.gradle (Module: app) dosyasında, yaşam döngüsü bileşenlerinin 2.2.0 sürümünü kullanın:

    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
    implementation "androidx.activity:activity-ktx:1.1.0"

    ViewModel'i bir Parçadan kullanmak istiyorsanız, şunu kullanın:

    implementation "androidx.fragment:fragment-ktx:1.2.2"

    fragment-ktx otomatik olarak activity-ktx'i içerir, bu nedenle her ikisini de bağımlılıklarda belirtmenize gerek yoktur.

  2. Android bölümünde Java 8 belirtmeniz gerekiyor:

    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. Parçanızda veya Faaliyetinizde, içe aktarmayı şu şekilde değiştirin:

    androidx.activity.viewModels'i içe aktar

  4. Bir ViewModel oluşturma kodu şu hale gelir:

    val viewModel: CalculatorViewModel by viewModels()

    onun yerine

    val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)

    ViewModel nesnesini şu şekilde kullanın:

    val viewModel: CalculatorViewModel by viewModels()
    
    viewModel.newNumber.observe(this, Observer<String> { 
        stringResult -> newNumber.setText(stringResult) 
    })

    burada newNumer bir LiveData amacı,

    Aktivitenin Görünüm Modelini paylaşmak istediğiniz bir Parçada,

    val viewModel: CalculatorViewModel by activityViewModels()

Bu, Activity örneğini (kullanımdan kaldırılmış) ViewModelProviders.of()işlevde geçirmeye eşdeğerdir .


17

ViewModelProviders.of () kullanımdan kaldırıldı. görüntü açıklamasını buraya girin

ViewModelProvider yapıcılarını, artık varsayılan ViewModelProvider.Factory rolünü işledikleri için doğrudan kullanın.

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

13

Evet @ Tarek, kullanımdan kaldırıldı. Şimdi AndroidX ile kullanın:

val yourViewModel = ViewModelProvider.NewInstanceFactory().create(YourVideoModel::class.java)

5
Bu cevap yanlış. Bir kullanmalısınız, ViewModelProvider(viewModelStoreOwner, factory).get(YourVideoModel::class.java)aksi takdirde onCleared()doğru çalışmayacaksınız ve ViewModel, yapılandırma değişikliğinde tutulmayacaktır. Bu cevabı kullanmayın.
EpicPandaForce

13

Muhtemelen şunları kullanabilirsiniz:

val viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)

android.arch.lifecycle:extensions:1.1.1bağımlılık eklemeye gerek kalmadan .



8

Kullanıyorum android Xve bu sorunu da yaşadım .

Her şeyden önce , bu bağımlılıkları aşağıdakilere eklemelisiniz Gradle:

implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" 

Benim durumumda, $ lifecycle_version 2.2.0-rc02

İkincisi: için içe aktarma şu şekilde ViewModelProviderolmalıdır:

import androidx.lifecycle.ViewModelProvider

VIewModel'inizi aşağıdaki örnekler gibi başlatabilirsiniz:

val viewModel = ViewModelProvider(this, YourFactoryInstace).get(MainViewModel::class.java)

val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

cevabınız için teşekkür ederim, ancak onu kullandığımda modeli gözlemleyin ve alanlar veri bağlama artık çalışmıyor
Mosa

Sanırım androidx.lifecycle:lifecycle-compilerartık geçersiz androidx.lifecycle:lifecycle-common-java8.
Bink

8

Aslında, ViewModelProviders.of()yöntem kaputun altında ne işe yarar?

@Deprecated
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
    return new ViewModelProvider(fragment);
}

FragmentBir argüman olarak alır , ViewModelProvidernesneyi oluşturur ve parçayı doğrudan kurucuya aktarır ViewModelProvider.

Biz de aynı şekilde kullanabiliriz.

Örn: Daha önce:

OurViewModel mOurViewModel = ViewModelProviders.of(this).get(OurViewModel.class);

Sonra:

OurViewModel mOurViewModel = new ViewModelProvider(this).get(OurViewModel.class);

Bir Fabrikası uygularsanız, başka bir yolu var: ViewModelProvidera hem beklediği bir kurucuya sahip ViewModelStoreOwnerve Factory.
russellhoff


3

Uzman değilim ama Java'da sorunumu çözen bir kod satırım var. Umarım bu birine yardımcı olur.

viewModel = 
new ViewModelProvider
.AndroidViewModelFactory(getApplication())
.create(ViewModel.class);

Dediğim gibi daha fazla ayrıntı vermeyi çok isterim, ancak bu benim için bu sorunu çözdü.


Bu kod yanlış, onCleared()bu şekilde çağrılmayacak ve ViewModel'iniz her seferinde yeniden oluşturulacak (yapılandırma değişiklikleri için saklanmaz).
EpicPandaForce

Belli bir örnekle biraz daha açıklar mısınız, hatamı ne düzeltir? Lütfen açıklamaya bir referans veya her şeyi daha açık hale getirecek herhangi bir şey yapıştırın
ZeePee

viewModel = new ViewModelProvider(this).get(MyViewModel.class). Bunu AndroidViewModelalamazsanız, ApplicationYaşam Döngüsü ve Etkinlik / Parça arasında bir sürüm uyuşmazlığınız var demektir.
EpicPandaForce

Tamam, yani getApplicationContext çağrısı yanlış mı? GetContext mi olmalı?
ZeePee

1
Sorun, a new ViewModelProvider.AndroidViewModelFactory(yerine a oluşturmaktır new ViewModelProvider(.
EpicPandaForce

3

Bunu kullan:

YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);

2

Bunun yerine bunu kullanabilirsiniz:

viewModel= ViewModelProvider(this).get(YourViewModel::class.java)

Parantez içindeki "bu", YourViewModel örneğinin sahibidir.


1

Bu cevap Java içindir, ancak ana noktayı anlayabilirsiniz. Çözüm, ViewModelProvider kullanmanız gerekmesidir çünkü ViewModelProviders kullanımdan kaldırılmıştır :

//Do not forget import it.
import androidx.lifecycle.AndroidViewModel;

ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);

Örnek kullanım:

YourViewModel yourViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(YourViewModel.class);

Ayrıca, Gradle Bağımlılıklarını güncellemeyi unutmayın : Son sürümleri için burayı kontrol edin

implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'

!!! Ancak dikkatli olun çünkü bazı cevaplar bu çözümü öneriyor ancak benim için işe yaramadı:

yourViewModel = new ViewModelProvider(this).get(YourViewModel.class);

Çünkü bu şekilde kullandığımda, Hata Mesajının altına düştüm:

Neden olduğu: java.lang.RuntimeException: com.canerkaseler.mvvmexample.ViewModel sınıfının bir örneği oluşturulamıyor

@canerkaseler


Bu cevap yanlış. Fabrikayı bir ViewModelProvider'a geçirmeniz gerekir. Doğrudan çağırırsanız create, onCleared()doğru çalışmayacaktır.
EpicPandaForce

Aslında, tam anlamıyla doğru cevabı kullanmamayı söyledin. Sizin androidx.coreve androidx.lifecyclebağımlılıklarınız arasında bir uyumsuzluk var gibi görünüyor .
EpicPandaForce

Normalde fabrikayı ViewModelProvider'a yazdım. Ancak siz onu sildiniz. ContactViewModel contactViewModel = new ViewModelProvider.AndroidViewModelFactory (getApplication ()). Create (ContactViewModel.class); Cevabımdan neden sildin? Yanlış kodlar verdin.
canerkaseler

0

Hançer kullandığınızda, yapıcıda fabrikayı geçersiniz

  MobileViewModel mobileViewModel = new ViewModelProvider(this,providerFactory).get(MobileViewModel.class);

-2

Bu uygulamaya sahipseniz

'implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

Kullanmaya çalışmak viewModel = MainViewModel()


Bu, bir görünüm modelini somutlaştırmanın bir yolu değildir. Bunun için ViewModelProvider sınıfını kullanmalısınız
Emmanuel Mtali

-2

Bunu dene...

 LocationViewModel locationViewModel = new ViewModelProvider(this).get(LocationViewModel.class);

-5

bu şekilde çalışmalı

 viewModel = ViewModelProviders.of(this@MainActivity).get(MainActivityViewModel::class.java)

1
Kodunuz örnek olurken, sınıf, View Model sınıfının yaşam döngüsü olaylarına doğru şekilde yanıt vermesi için gereken görünüm durumuna bağlantı oluşturmayacaktır. Modelleri Görüntülemek için doğru şekilde örneklemeniz gerekir, böylece ebeveynlerinin yaşam döngülerini yanıtlar ve onurlandırırlar, aksi takdirde her seferinde yeni ve boş olarak yeniden oluşturulurlar.
Kenneth Argo

OP ve diğerleri tarafından yukarıda belirtildiği gibi; ViewModelProviders sınıfı kullanımdan kaldırıldı. Bakınız: developer.android.com/reference/androidx/lifecycle/…
Kenneth Argo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.