ViewModelProviders는 1.1.0에서 더 이상 사용되지 않습니다


148

에 대한 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의 새 인스턴스를 얻습니다.

더 이상 사용되지 않는 코드를 대체하는 아이디어가 있습니까?


싱글 톤 패턴을 사용하거나 AndroidX로 변경
Oussema Aroua

답변:


31

업데이트 2020-06-16 : 현재 ViewModelProviders 는 더 이상 사용되지 않으며 더 이상 사용해서는 안됩니다. 이 질문과 답변은 그렇지 않은 2018 년 말부터있었습니다. 이 질문과 답변은 ViewModelProvidersAndroidX 버전이 아닌의 이전 Architecture Components 버전에도 적용 됩니다.


최신 종속성을 사용하는 경우 해당 android.arch.lifecycle:extensions:1.1.1클래스가 없습니다 ViewModelProviders.

그렇습니다. 이것을 증명하려면 :

  • Android Studio 3.2.1에서 새 프로젝트 생성 (Kotlin, 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에 대한 설명서로 이동하면서이 클래스는 API 레벨 1.1.0에서 더 이상 사용되지 않습니다. ViewModelProvider.AndroidViewModelFactory를 사용하십시오.

이 주석은 ViewModelProviders.DefaultFactory클래스 항목 아래에 있으며 해당 클래스를 참조합니다 ViewModelProviders.

설명서 스크린 샷

더 이상 사용되지 않는 코드를 대체하는 아이디어가 있습니까?

사용하십시오 ViewModelProviders.


1
@TareKKhoury : 설명 할 것입니다! 어떤 모듈이 어떤 종속성을 필요로하는지 추적하는 것은 어려운 일입니다. 나는 당신이 그것을 작동하게되어 기쁘다!
CommonsWare

13
이것은 더 이상 사실이 아니며 더 ViewModelProviders.of()이상 존재하지 않습니다.
EpicPandaForce

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 ()는 더 이상 사용되지 않습니다. Fragment 또는 FragmentActivity를 새 ViewModelProvider (ViewModelStoreOwner) 생성자로 전달하여 동일한 기능을 수행 할 수 있습니다. (aosp / 1009889)
Raghu Krishnan R

32
Java 해당 :YourViewModel viewModel = new ViewModelProvider(this).get(YourViewModel.class);
ban-geoengineering

16
언젠가 Google에서 더 이상 사용하지 TextView않거나 EditText새로운 구성 요소를 도입 할까 걱정됩니다 .
Pranjal Choladhara

4
androidx lifecycle-viewmodel 2.1.0에는 팩토리가없는 생성자가 없습니다. 단순히 (this)를 사용하면 작동하지 않습니다. ViewModelProvider (ViewModelStoreOwner, Factory) 및 ViewModelProvider (ViewModelStore, Factory)는 유일한 생성자
DevinM

70

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

팩토리 객체를 전달하지 않고


1
build.gradle에서 다음을 사용해야합니다. 구현 "androidx.lifecycle : lifecycle-viewmodel : $ lifecycle_version" developer.android.com/jetpack/androidx/releases/lifecycle에 라이프 사이클 확장의 API는 더 이상 사용되지 않습니다. 대신 필요한 특정 수명주기 아티팩트에 대한 종속성을 추가하십시오.
Kenneth Argo

40

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

자바의 새로운 코드 :

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

또는 Kotlin의 경우 :

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

ViewModelProvider isntsance를 유지하거나 다시 생성해야합니까?이 경우 모든 기본 인스턴스도 삭제됩니다. 아이디어가 프래그먼트 / 액티비티의 수명주기를 보는 것이라면 다시 만들 필요는 없습니다
TheRealChx101

31

더 이상 사용되지 않음 : ViewModelProviders.of(this, provider).get(VM::class.java)

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


4
정확히 내가 찾던 것.
Rahul Bali

22

2020 년 초 Google은 androidx 수명주기 라이브러리 버전 2.2.0에서 ViewModelProviders 클래스를 더 이상 사용하지 않습니다 .

더 이상 ViewModelProviders를 사용하여 ViewModel의 인스턴스를 만들 필요가 없습니다. 대신 Fragment 또는 Activity 인스턴스를 ViewModelProvider 생성자에 전달할 수 있습니다.

다음과 같은 코드를 사용하는 경우 :

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

ViewModelProviders가 더 이상 사용되지 않는다는 경고가 표시 됩니다.

더 이상 사용되지 않는 라이브러리를 사용하지 않으려면 다음과 같이 변경하십시오.

  1. build.gradle (모듈 : app) 파일에서 라이프 사이클 구성 요소 버전 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"

    fragment-ktx에는 활동 -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을 공유하려는 프래그먼트에서

    val viewModel: CalculatorViewModel by activityViewModels()

(더 이상 사용되지 않는) ViewModelProviders.of()함수 에서 Activity 인스턴스를 전달하는 것과 같습니다 .


17

ViewModelProviders.of ()는 더 이상 사용되지 않습니다. 여기에 이미지 설명을 입력하십시오

이제 기본 ViewModelProvider.Factory 역할을 처리 할 때 ViewModelProvider 생성자를 직접 사용하십시오.

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

13

예 @Tarek, 더 이상 사용되지 않습니다. AndroidX와 함께 사용하십시오 :

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

5
이 답변은 잘못되었습니다. 당신은 사용되어야한다 ViewModelProvider(viewModelStoreOwner, factory).get(YourVideoModel::class.java), 그렇지 않으면 당신의 onCleared()뜻이 제대로 작동하지 및 뷰 모델은 설정 변경을 통해 유지되지 않습니다. 이 답변을 사용하지 마십시오.
EpicPandaForce

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 관찰 및 필드 데이터 바인딩이 더 이상 작동하지 않습니다
Mosa

androidx.lifecycle:lifecycle-compiler의해 더 이상 사용되지 않는다고 생각 합니다 androidx.lifecycle:lifecycle-common-java8.
Bink

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

팩토리를 구현하면 다른 방법 이 있습니다. ViewModelProvidera ViewModelStoreOwner와 a를 모두 기대하는 생성자 가 Factory있습니다.
russellhoff


3

나는 전문가가 아니지만 Java에서 내 문제를 해결하는 코드 줄이 있습니다. 이것이 누군가를 돕기를 바랍니다.

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

내가 말했듯이 자세한 내용을 제공하고 싶지만이 문제가 해결되었습니다.


이 코드는 잘못되었습니다. onCleared()이런 식으로 호출되지 않으며 매번 (모델 변경을 위해 유지되지 않는) ViewModel이 다시 생성됩니다.
EpicPandaForce

특정 예를 통해 조금 더 설명해 주시겠습니까? 실수를 어떻게 해결할 수 있습니까? 설명이나 더 명확하게 할 수있는 내용에 대한 언급을 붙여 주시기 바랍니다.
ZeePee

viewModel = new ViewModelProvider(this).get(MyViewModel.class). 을 AndroidViewModel얻지 못하면 Application수명주기와 활동 / 조각간에 버전이 일치하지 않습니다.
EpicPandaForce

좋아, getApplicationContext 호출이 잘못 되었습니까? getContext 여야합니까?
ZeePee

1
문제는 new ViewModelProvider.AndroidViewModelFactory(대신을 만드는 중입니다 new ViewModelProvider(.
EpicPandaForce

3

이것을 사용하십시오 :

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

2

대신 이것을 사용할 수 있습니다 :

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

괄호 안의 "this"는 YourViewModel 인스턴스의 소유자입니다.


1

이 답변은 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 Dependencies 업데이트를 잊지 마십시오 : 최신 버전은 여기를 확인하십시오 .

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의 인스턴스를 작성할 수 없습니다.

아리따움


이 답변은 잘못되었습니다. 팩토리를 ViewModelProvider에 전달해야합니다. 직접 호출하면 경우 create, 다음 onCleared()올바른 작동하지 않습니다.
EpicPandaForce

사실, 당신은 말 그대로 정답을 사용하지 말라고 말했습니다. 당신 androidx.core과 당신의 androidx.lifecycle의존성 이 일치하지 않는 것 같습니다 .
EpicPandaForce

일반적으로 ViewModelProvider에 팩토리를 썼습니다. 그러나 삭제했습니다. ContactViewModel contactViewModel = 새 ViewModelProvider.AndroidViewModelFactory (getApplication ()). create (ContactViewModel.class); 내 답변에서 왜 삭제 했습니까? 잘못된 코드를 전달했습니다.
canerkaseler

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
코드에서 인스턴스를 생성하는 동안 클래스는 수명주기 이벤트에 올바르게 응답하기 위해 뷰 모델 클래스가 필요한 뷰 상태에 대한 연결을 만들지 않습니다. 뷰 모델을 올바른 방식으로 인스턴스화하여 부모의 수명주기에 응답하고 존중해야합니다. 그렇지 않으면 매번 신선하고 빈 상태로 다시 생성됩니다.
Kenneth Argo

OP와 다른 사람들에 의해 위에서 언급 한 바와 같이; ViewModelProviders 클래스는 사용되지 않습니다. 참조 : developer.android.com/reference/androidx/lifecycle/…
Kenneth Argo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.