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 2018

回答:


31

更新2020-06-16現在 ViewModelProviders非推奨であり、今後は使用しないでください。この質問と回答は、2018年後半からそうではなかったときのものです。この質問と回答はViewModelProviders、AndroidXエディションではなく、の古いアーキテクチャコンポーネントエディションにも当てはまります。


最新の依存関係を使用する場合、その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 2018

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:デリゲートのケースを修正


160
私はグーグルによる絶え間ない「減価償却」サイクルにうんざりしています。
AFD、

3
ViewModelProviders.of()は非推奨になりました。FragmentまたはFragmentActivityを新しいViewModelProvider(ViewModelStoreOwner)コンストラクターに渡して、同じ機能を実現できます。(aosp / 1009889)
ラグークリシュナンR

31
Javaでの同等機能:YourViewModel viewModel = new ViewModelProvider(this).get(YourViewModel.class);
ban-geoengineering

16
いつの日かGoogleが廃止されます場合、私は心配しTextViewたりEditTextして、新しいコンポーネントを紹介します。
Pranjal Choladhara

4
androidx lifecycle-viewmodel 2.1.0には、ファクトリーなしのコンストラクターはありません。単に(これ)を使用しても機能しません。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で次を使用する必要があります。implementation "androidx.lifecycle:lifecycle-viewmodel:$ lifecycle_version" developer.android.com/jetpack/androidx/releases/lifecycleに記載されているとおり 、lifecycle-extensionsのAPIは非推奨になりました。代わりに、必要な特定のライフサイクルアーティファクトの依存関係を追加します。
ケネス・アルゴ

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

JAVAの新しいコード:

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

またはKotlinの場合:

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

ViewModelProviderのインスタンスを保持するか、それを再作成する必要がありますか。その場合、すべての基になるインスタンスも破棄されます。フラグメント/アクティビティのライフサイクルを監視することが目的である場合は、再作成する理由はありません
TheRealChx101


21

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(モジュール:アプリ)ファイルで、ライフサイクルコンポーネントのバージョン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を共有するフラグメントでは、次を使用します

    val viewModel: CalculatorViewModel by activityViewModels()

これは、(非推奨の)ViewModelProviders.of()関数でActivityインスタンスを渡すことと同じです。


17

ViewModelProviders.of()は非推奨になりました。 ここに画像の説明を入力してください

ViewModelProviderコンストラクターは、デフォルトのViewModelProvider.Factoryロールを処理するようになったため、直接使用してください。

 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()は正しく使用できず、ViewModelは設定変更後も保持されません。この回答は使用しないでください。
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

2番目: のインポートは次の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
ビンク

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があります。a ViewModelStoreOwnerとaの両方を期待するコンストラクタがありFactoryます。
ラッセルホフ


3

私はエキスパートではありませんが、Javaの問題を解決するコード行があります。これが誰かを助けることを願っています。

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

先ほど述べたように、詳細を提供したいのですが、これでこの問題は解決しました。


このコードは間違っており、onCleared()このように呼び出されず、ViewModelが毎回再作成されます(構成変更のために保持されません)。
EpicPandaForce

特定の例を使ってもう少し説明してもらえますか?私の間違いを修正するにはどうすればよいですか?説明への参照または説明を
わかりやすく

viewModel = new ViewModelProvider(this).get(MyViewModel.class)。をAndroidViewModel取得できないApplication場合は、ライフサイクルとアクティビティ/フラグメントのバージョンが一致していません。
EpicPandaForce

OK、それで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の依存関係を彼らの最後のバージョンはこちらをチェック

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に渡す必要があります。を直接呼び出すとcreateonCleared()正しく機能しません。
EpicPandaForce

実際、あなたは文字通り正しい答えを使わないように言っただけです。あなたandroidx.coreとあなたのandroidx.lifecycle依存関係の間に不一致があったように聞こえます。
EpicPandaForce

通常、ファクトリをViewModelProviderに書き込みました。ただし、削除しました。ContactViewModel contactViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication())。create(ContactViewModel.class); なぜあなたは私の答えでそれを削除したのですか?間違ったコードを渡しました。
canerkaseler

0

ダガーを使用すると、コンストラクターでファクトリーを渡します

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


-2

これを試して...

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

-5

このように機能するはずです

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

1
コードはインスタンス化しますが、クラスはライフサイクルイベントに正しく応答するためにView Modelクラスを必要とするビューステートへの接続を作成しません。ビューモデルを正しい方法でインスタンス化して、親のライフサイクルに応答して尊重する必要があります。そうしないと、毎回新鮮で空白に再作成されます。
ケネスアルゴ

上記のようにOPと他の人が述べた。ViewModelProvidersクラスは廃止されました。参照:developer.android.com/reference/androidx/lifecycle/...
ケネス・アルゴ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.