ViewModelProviders 1.1.0 में पदावनत है


148

को देखते हुए गूगल डॉक्स के लिए ViewModel, वे कैसे एक पाने के लिए पर नमूना कोड के नीचे प्रदर्शित ViewModel:

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

नवीनतम निर्भरता का उपयोग करते android.arch.lifecycle:extensions:1.1.1समय ऐसा कोई वर्ग नहीं होता हैViewModelProviders

के लिए प्रलेखन के लिए जा रहे हैंViewModelProviders , मैंने एक टिप्पणी देखी:

इस कक्षा को एपीआई स्तर 1.1.0 में पदावनत किया गया था। ViewModelProvider.AndroidViewModelFactory का उपयोग करें

समस्या यह है कि जब उपयोग करने की कोशिश की जा रही है, तो इसका उदाहरण प्राप्त करने के लिए ViewModelProvider.AndroidViewModelFactoryएक समान ofविधि नहीं मिल सकती है ViewModel

मैंने क्या करने की कोशिश की:

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

इसलिए विधि का नाम create, मुझे हर बार जब मैं कॉल करता हूं, तो ViewModel का एक नया उदाहरण मिलता है, जो कि मैं उसके बाद नहीं हूं।

किसी भी विचार ऊपर पदावनत कोड के प्रतिस्थापन क्या है?


सिंगलटन पैटर्न का उपयोग करें या AndroidX में परिवर्तन करें
Oussema Aroua

जवाबों:


31

अद्यतन 2020-06-16 : वर्तमान ViewModelProviders में पदावनत है और अब इसका उपयोग नहीं किया जाना चाहिए। यह सवाल और जवाब 2018 के अंत से था, जब ऐसा नहीं था। यह प्रश्न और उत्तर पुराने आर्किटेक्चर कंपोनेंट्स संस्करण के लिए हैं ViewModelProviders, न कि AndroidX संस्करण।


नवीनतम निर्भरता का उपयोग करते android.arch.lifecycle:extensions:1.1.1समय ऐसा कोई वर्ग नहीं होता हैViewModelProviders

हाँ वहाँ है। इसे प्रदर्शित करने के लिए:

  • Android Studio 3.2.1 (कोटलिन, minSdkVersion21, "खाली गतिविधि" टेम्पलेट के साथ एक नया प्रोजेक्ट बनाएं )

  • मॉड्यूल 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 के दस्तावेज़ के लिए जा रहे हैं, मैंने एक टिप्पणी यह ​​कहते हुए देखी: इस वर्ग को एपीआई स्तर 1.1.0 में पदावनत किया गया था। ViewModelProvider.AndroidViewModelFactory का उपयोग करें

वह टिप्पणी ViewModelProviders.DefaultFactoryकक्षा में प्रवेश के नीचे है और उस वर्ग को संदर्भित करती है, न कि ViewModelProviders:

प्रलेखन स्क्रीनशॉट

किसी भी विचार ऊपर पदावनत कोड के प्रतिस्थापन क्या है?

का उपयोग करें ViewModelProviders


1
@TareKKhoury: जो इसे समझाएगा! किन मॉड्यूलों को ध्यान में रखते हुए कौन सी निर्भरता निश्चित रूप से एक चुनौती हो सकती है। मुझे यह सुनकर खुशी हुई कि आप इसे काम कर रहे हैं!
कॉमन्सवेयर

13
यह अब सच नहीं है, ViewModelProviders.of()अब मौजूद नहीं है।
एपिकपांडाफॉरेस

323

मैं जीवनचक्र-एक्सटेंशन का उपयोग करता हूं 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

2020/06/25: प्रतिनिधि के मामले को सही किया


161
मैं Google द्वारा निरंतर "मूल्यह्रास" चक्र के बीमार की तरह हूं।
AFD

3
ViewModelProviders.of () को हटा दिया गया है। आप एक ही कार्यक्षमता को प्राप्त करने के लिए नए ViewModelProvider (ViewModelStoreOwner) कंस्ट्रक्टर को एक फ्रैगमेंट या फ्रैगमेंटएक्टिविटी पास कर सकते हैं। (aosp / 1009889)
रघु कृष्णन R

32
जावा समतुल्य:YourViewModel viewModel = new ViewModelProvider(this).get(YourViewModel.class);
प्रतिबंध-जियोइंजीनियरिंग

16
मुझे चिंता है कि अगर किसी दिन Google एक नया घटक शुरू करेगा TextViewया EditTextशुरू करेगा ।
प्रांजल चोलधारा

4
Androidx जीवनचक्र-दृश्यमोडल 2.1.0 में एक कारखाने के बिना एक निर्माता नहीं है। बस (यह) उपयोग करने से काम नहीं चलता। ViewModelProvider (ViewModelStoreOwner, Factory) और ViewModelProvider (ViewModelStore, फैक्टरी) एकमात्र निर्माणकर्ता हैं
DevinM

70

जैसा कि @FantasyFang ने अपने उत्तर में उल्लेख किया है, lifecycle:lifecycle-extensionsइस क्षण के लिए अंतिम संस्करण का उपयोग करें 2.2.0-alpha03। तो आपको अपने build.gradle फ़ाइल को निम्न पंक्ति में जोड़ना चाहिए:

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

जो लोग जावा का उपयोग कर रहे हैं, इसे हल करने के लिए, उन तर्कों को सीधे ViewModelProvider के कंस्ट्रक्टर के पास दें :

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

या यदि आप किसी कारखाने का उपयोग नहीं करते हैं, तो बस उपयोग करें:

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

अपने कारखाने वस्तु को पारित किए बिना।


1
आपको build.gradle: कार्यान्वयन "androidx.lifecycle: lifecycle-viewmodel: $ lifecycle_version" का उपयोग करना चाहिए जैसा कि डेवलपर में बताया गया है ।android.com/jetpack/androidx/releases- lifecycle जीवनचक्र-एक्सटेंशन में API को हटा दिया गया है। इसके बजाय, आपके द्वारा आवश्यक विशिष्ट जीवनचक्र की कलाकृतियों के लिए निर्भरता जोड़ें।
केनेथ आर्गो

40

2.2.0 के रूप में। जीवनचक्र-विस्तार को हटा दिया गया है। Google दस्तावेज़ीकरण देखें ।

यह पृष्ठ से कटौती है:

जीवनचक्र-विस्तार में एपीआई को हटा दिया गया है। इसके बजाय, आपके द्वारा आवश्यक विशिष्ट जीवनचक्र की कलाकृतियों के लिए निर्भरता जोड़ें।

नए पुस्तकालय हैं:

// 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}"

जावा के लिए नया कोड:

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

या कोटलिन के लिए:

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

क्या हम ViewModelProvider isntsance रखते हैं या इसे फिर से बनाना है, इस स्थिति में, सभी अंतर्निहित उदाहरण भी नष्ट हो जाएंगे। अगर इसे खंड / गतिविधि के जीवनचक्र को देखना है तो मैं इसे फिर से बनाने का कारण नहीं हूं
TheRealChx101


21

2020 की शुरुआत में, Google ने Androidx जीवनचक्र पुस्तकालय के संस्करण 2.2.0 में ViewModelProviders वर्ग को हटा दिया है

ViewModelProviders का उपयोग करना अब ViewModel का एक उदाहरण बनाने के लिए आवश्यक नहीं है, आप इसके बजाय ViewModelProvider निर्माता के लिए अपने फ़्रैगमेंट या गतिविधि का उदाहरण दे सकते हैं।

यदि आप कोड का उपयोग करते हैं जैसे:

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

आपको एक चेतावनी मिलेगी कि ViewModelProviders को पदावनत कर दिया गया है।

पदावनत पुस्तकालयों के उपयोग से बचने के लिए, निम्नलिखित परिवर्तन करें:

  1. बिल्ड.ग्रेडल (मॉड्यूल: ऐप) फ़ाइल में, जीवन चक्र घटकों के संस्करण 2.2.0 का उपयोग करें:

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

    यदि आप इसके बजाय एक Fragment से ViewModel का उपयोग करना चाहते हैं

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

    टुकड़ा-केटीएक्स में स्वचालित रूप से गतिविधि-केटीएक्स शामिल है, इसलिए आपको दोनों निर्भरताओं में निर्दिष्ट करने की आवश्यकता नहीं है।

  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. अपने Fragment या गतिविधि में, आयात को निम्न में बदलें:

    आयात androidx.activity.viewModels

  4. एक ViewModel बनाने के लिए कोड बनता है:

    val viewModel: CalculatorViewModel by viewModels()

    के बजाय

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

    दृश्यमॉडल ऑब्जेक्ट का उपयोग इस प्रकार करें:

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

    कहाँ पे newNumer एक LiveData ऑब्जेक्ट है

    एक फ्रैगमेंट में जिसे आप एक्टिविटी के व्यूमॉडल को साझा करना चाहते हैं, आप उपयोग करेंगे

    val viewModel: CalculatorViewModel by activityViewModels()

यह (पदावनत) ViewModelProviders.of()फ़ंक्शन में गतिविधि उदाहरण पास करने के बराबर है ।


17

ViewModelProviders.of () को हटा दिया गया है। यहाँ छवि विवरण दर्ज करें

सीधे ViewModelProvider निर्माणकर्ताओं का उपयोग करें क्योंकि वे अब डिफ़ॉल्ट ViewModelProvider.Factory भूमिका संभालते हैं।

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

13

हां @ तारेक, यह पदावनत है। AndroidX के साथ अब उपयोग करें:

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

5
यह उत्तर गलत है। आप का उपयोग करना चाहिए ViewModelProvider(viewModelStoreOwner, factory).get(YourVideoModel::class.java)अन्यथा आपका onCleared()काम सही ढंग से नहीं होगा, और ViewModel को कॉन्फ़िगर परिवर्तन में नहीं रखा जाएगा। इस उत्तर का उपयोग न करें।
एपिकपांडाफॉरेस

13

शायद आप सिर्फ उपयोग कर सकते हैं:

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

android.arch.lifecycle:extensions:1.1.1निर्भरता के रूप में जोड़ने की आवश्यकता के बिना ।



8

मैं उपयोग कर रहा हूं 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)

आपके उत्तर के लिए धन्यवाद, लेकिन जब मैं इसका उपयोग करता हूं, तो viewmodel निरीक्षण और फ़ील्ड डेटाबाइंडिंग अब काम नहीं करता है
मोसा

मेरा मानना androidx.lifecycle:lifecycle-compilerहै कि इसका पालन किया जाता है androidx.lifecycle:lifecycle-common-java8
बिंक

8

वास्तव में, 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);

यदि आप एक कारखाने को लागू करते हैं, तो आपके पास एक और तरीका है: ViewModelProviderएक कंस्ट्रक्टर है जो ए ViewModelStoreOwnerऔर ए दोनों की उम्मीद करता है Factory
रुसलफॉफ़


3

मैं कोई विशेषज्ञ नहीं हूं, लेकिन मेरे पास कोड की एक पंक्ति है जो जावा में मेरी समस्या को हल करती है। आशा है कि यह किसी की मदद करता है।

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

जैसा कि मैंने कहा कि मुझे अधिक विवरण प्रदान करना अच्छा लगेगा, लेकिन इसने मेरे लिए यह समस्या तय कर दी।


यह कोड गलत है, onCleared()इसे इस तरह से नहीं कहा जाएगा और आपका ViewModel हर बार फिर से बनाया जाएगा (कॉन्फ़िगर परिवर्तनों के लिए नहीं रखा गया है)।
एपिकपांडाफॉरेस

क्या आप एक निश्चित उदाहरण के साथ थोड़ा और समझा सकते हैं, मेरी गलती को क्या ठीक करेगा? कृपया, स्पष्टीकरण या ऐसी किसी भी चीज़ का संदर्भ दें, जो चीजों को स्पष्ट कर दे
ZeePee

viewModel = new ViewModelProvider(this).get(MyViewModel.class)। यदि आपका AndroidViewModelनहीं मिलता है Application, तो आप जीवनचक्र और गतिविधि / टुकड़ा के बीच एक संस्करण बेमेल है।
इपिकपांडा

ठीक है, तो getApplicationContext को कॉल करना गलत है? यह सिर्फ getContext होना चाहिए?
ZeePee

1
समस्या एक के new ViewModelProvider.AndroidViewModelFactory(बजाय बना रही है new ViewModelProvider(
इपिकपांडाफेयर

3

इसे इस्तेमाल करो:

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

2

आप इसके बजाय इसका उपयोग कर सकते हैं:

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

कोष्ठकों में "यह" YourViewModel उदाहरण का स्वामी है।


1

यह उत्तर जावा के लिए है, लेकिन आप मुख्य बिंदु को समझ सकते हैं। समाधान यह है कि आपको 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);

इसके अलावा, अद्यतन ग्रेड निर्भरता को मत भूलना : उनमें से अंतिम संस्करणों के लिए यहां देखें

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


यह उत्तर गलत है। आपको कारखाने को एक ViewModelProvider पास करने की आवश्यकता है। यदि आप सीधे आह्वान करते हैं create, तो onCleared()सही काम नहीं करेगा।
एपिकपांडाफॉरेस

वास्तव में, आपने सचमुच कहा कि सही उत्तर का उपयोग न करें। लगता है जैसे आपके androidx.coreऔर आपके androidx.lifecycleआश्रितों के बीच एक बेमेल संबंध था ।
एपिकपांडाफॉरेस

आम तौर पर मैंने ViewModelProvider के कारखाने को लिखा था। हालाँकि, आपने इसे हटा दिया। ContactViewModel contactViewModel = नया ViewModelProvider.AndroidViewModelFactory (getApplication ()) बनाएँ। (ContactViewModel.class); आपने मेरे उत्तर पर इसे क्यों हटा दिया? आपने गलत कोड पारित किए हैं।
कैनकेसरेलर

0

जब आप डैगर का उपयोग करते हैं तो आप कंस्ट्रक्टर में कारखाना पास करेंगे

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

-2

यदि आपके पास यह कार्यान्वयन है

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

उपयोग करने का प्रयास करें viewModel = MainViewModel()


यह एक दृश्य मॉडल को तुरंत करने का एक तरीका नहीं है। आपको इसके लिए ViewModelProvider वर्ग का उपयोग करना होगा
Emmanuel Mtali

-2

इसे इस्तेमाल करे...

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

-5

इसे इस तरह से काम करना चाहिए

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

1
जबकि आपका कोड उदाहरण देगा कि क्लास दृश्य जीवन वर्ग से सही ढंग से जीवन चक्र की घटनाओं का जवाब देने के लिए आवश्यक व्यू स्टेट से संबंध नहीं बनाएगी। आपको मॉडल को सही तरीके से देखने की आवश्यकता है ताकि वे अपने माता-पिता के जीवन चक्रों का जवाब दें और उन्हें सम्मानित करें और उन्हें हर बार ताज़ा और रिक्त बनाया जाए।
केनेथ आर्गो

जैसा कि ओपी और अन्य ने ऊपर उल्लेख किया है; ViewModelProviders वर्ग को हटा दिया गया है। देखें: developer.android.com/reference/androidx/lifecycle/…
केनेथ आर्गो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.