SharedPreferencesのcommit()とapply()の違いは何ですか


431

SharedPreferencesAndroidアプリで使用しています。私は共有設定の両方commit()apply()メソッドを使用しています。AVD 2.3を使用するとエラーは表示されませんが、AVD 2.1でコードを実行するとapply()メソッドにエラーが表示されます。

では、これら2つの違いは何ですか?そして、使用するだけでcommit()問題なく設定値を保存できますか?


115
これは1年前のものですが、とにかくコメントしますが、明白かもしれませんが、答えはどれもこの点を示してapply()いませんcommit()。同期中にディスクI / Oを非同期で実行します。したがってcommit()、UIスレッドから呼び出してはいけません。
michiakig

注目すべきは、複数のSharedPreferences.Editorオブジェクトが使用されている場合、最後に呼び出されたものが優先されますapply()。したがって、アプリケーションでSharedPreferences.Editorが1つだけ使用されていることを確認するとapply()commit()安全に代わりに使用できます。
aoeu

2
Android Studio Lintの警告に従って:commit()はデータを即座に同期して保存します。ただし、apply()は非同期で(バックグラウンドで)保存するため、パフォーマンスが向上します。そのため、戻り値のタイプを気にしない場合(データが正常に保存されたかどうかにかかわらず)、apply()がcommit()よりも優先されます。
Rahul Raina 2018

使用時にリント警告を無効にする方法はありcommit()ますか?
QED

回答:


653

apply() 2.3で追加されました、それはコミットします 成功または失敗を示すブール値を返さます。

commit()保存が成功した場合はtrueを返し、falseを返しますそれ以外の場合。

apply() Android開発チームが戻り値に誰も気づかなかったことに気づいたために追加されました。非同期であるため、適用はより高速です。

http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply()


8
この答えは真実ですが、上の@spacemanakiのコメントも真実だと思います
Aksel Fatih

58
commit()はデータを永続ストレージにすぐに書き込みますが、apply()はバックグラウンドで処理します。
capt.swag 2015年

18
競合状態が発生しますか?
ChrisMcJava

42
apply()を使用して何かを記述し、直後に読み込もうとするとどうなりますか?読み取りは最新の値を提供することが保証されていますか?ドキュメントは、apply()を実行した後に別のcommit()が発生すると、apply()がディスクに永続化されるまでブロックされるため、「書き込み」操作に関してはこの問題が発生しないことが明らかになっています、しかしあなたがすぐに書いて読んでいるならどうですか?私のテストでは、最新の値が返されますが、これが100%保証されているかどうかを知りたいです。
ティアゴ

22
commit()のインスタンスをapply()で置き換えるのが安全です
。developer.android.com/ reference / android / content /…を

221

tl; dr:

  • commit()データを同期的に書き込みます(呼び出し元のスレッドをブロックします)。次に、操作の成功について通知します。
  • apply()データが非同期で書き込まれるようにスケジュールします。それは通知しない操作の成功についてあなたを。
  • 保存してgetXメソッドを使用しapply()すぐに読み取ると、新しい値が返されます!
  • あなたが呼ばれた場合apply()、いくつかの点で、それはまだ実行だ、への呼び出しcommit()すべての過去は、通話適用するまでブロックします、現在のコミット呼び出しが終了しています。

SharedPreferences.Editorドキュメントからの詳細情報:

設定を永続ストレージに同期的に書き込むcommit()とは異なり、apply()は変更をメモリ内のSharedPreferencesにすぐにコミットしますが、ディスクへの非同期コミットを開始するため、エラーは通知されません。このSharedPreferencesの別のエディターが、apply()が未解決の間に通常のcommit()を実行すると、commit()は、すべての非同期コミットとコミット自体が完了するまでブロックします。

SharedPreferencesインスタンスはプロセス内のシングルトンであるため、戻り値を既に無視している場合は、commit()のインスタンスをapply()で置き換えても安全です。

SharedPreferences.Editorインターフェイスは、直接実装することは想定されていません。ただし、以前に実装していて、apply()がないというエラーが発生している場合は、apply()からcommit()を呼び出すだけです。


19
これはapply()非同期であり、保留中の書き込みがへの将来の呼び出しをブロックすることを述べているので、これははるかに良い答えcommit()です。
spaaarky21

22

commit()の代わりにapply()を使用すると問題が発生します。他の応答で前述したように、apply()は非同期です。「文字列セット」設定に加えられた変更が永続メモリに書き込まれないという問題が発生しています。

これは、プログラムを「強制拘留」した場合、またはAndroid 4.1を搭載したデバイスにインストールしたROMで、メモリの必要性のためにプロセスがシステムによって強制終了された場合に発生します。

設定を有効にしたい場合は、「apply()」の代わりに「commit()」を使用することをお勧めします。


同時スレッドが原因で問題が関連していないと確信していますか?apply()を送信した後、追加した内容を読み取るにはしばらく待つ必要があります。そうしないと、UIスレッドは、apply()のワーカースレッドが変更をコミットする前に読み取りを試みます。
Marco Altran 2014

文字列セットに関しては、stackoverflow.com
questions / 16820252 /…

@JoseLSegura-ドキュメントは別の方法で提案します: developer.android.com/intl/ja/reference/android/content/… "Androidコンポーネントのライフサイクルや、ディスクへの書き込みとapply()の相互作用について心配する必要はありません。フレームワーク状態を切り替える前に、apply()からのディスクへの書き込みが完了していることを確認してください。」あなたが見ているのはAndroidのバグなのか、それとも新しいバージョンで修正されているのかと思います。
ToolmakerSteve '19

ライブラリ「ProcessPhoenix」を使用してアプリをリセットすると、同じ問題が発生します。リセットを実行する直前に設定を保存していましたが、「適用」が機能しませんでした。
ElYeante

14

apply()を使用します。

変更をすぐにRAMに書き込み、待機してから内部ストレージ(実際の設定ファイル)に書き込みます。コミットは、変更を同期的に直接ファイルに書き込みます。


14
  • commit()同期的、apply()非同期的です

  • apply() void関数です。

  • commit() 新しい値が永続ストレージに正常に書き込まれた場合はtrueを返します。

  • apply() 状態が切り替わる前に保証が完了するため、Androidコンポーネントのライフサイクルについて心配する必要はありません

あなたがから返される使用価値をいけない場合commit()、あなたが使用しているcommit()、メインスレッドから使用apply()の代わりに、 commit()


13

ドキュメントは、違いのかなり良い説明を与えるapply()とのcommit()

とは異なりcommit()、設定を永続ストレージに同期的に書き込み、apply()その変更をメモリ内に SharedPreferencesすぐにコミットしますが、ディスクへの非同期コミットを開始するため、エラーは通知されません。これに関する別のエディターがa が未解決の間にSharedPreferences定期的にcommit()行う場合、すべての非同期コミットとコミット自体が完了するまではブロックされます。インスタンスは、プロセス内のシングルトンがあり、それは、任意のインスタンス置き換えることは安全だ とすでに戻り値を無視した場合を。apply()commit()SharedPreferencescommit()apply()


6

javadocから:

設定を永続ストレージに同期的に書き込むcommit()とは異なり、apply()は変更をメモリ内のSharedPreferencesにすぐにコミットしますが、ディスクへの非同期コミットを開始するため、エラーは通知されません。> Shared(Preferences)の別のエディターが> apply()が未解決の間に通常のcommit()を実行すると、commit()は、すべての非同期コミットとコミット自体が完了するまでブロックします


1

commit()とapply()の違い

SharedPreferenceを使用している場合、これら2つの用語に混乱する可能性があります。基本的にそれらはおそらく同じであるため、commit()とapply()の違いを明確にしましょう。

1.戻り値:

apply()成功または失敗を示すブール値を返さずにコミットします。 commit()保存が機能する場合はtrueを返し、それ以外の場合はfalseを返します。

  1. 速度:

apply()より速いです。 commit()遅いです。

  1. 非同期vs同期:

apply():非同期 commit():同期

  1. 原子:

apply():アトミック commit():アトミック

  1. エラー通知:

apply():いいえ commit():はい


どのようにapply()「速い」よりもcommit()?これらは基本的に、スレッドのルーパーに配置されるのと同じタスクを表します。commit()そのタスクをメインルーパーapply()に配置し、バックグラウンドで実行することで、メインルーパーにディスクI / Oタスクが発生しないようにします。
ティーザー

設定を永続ストレージに同期的に書き込むcommit()とは異なり、apply()は変更をメモリ内のSharedPreferencesにすぐにコミットしますが、ディスクへの非同期コミットを開始するため、エラーは通知されません。このSharedPreferencesの別のエディターが、apply()が未解決の間に通常のcommit()を実行すると、すべての非同期コミットが完了するまでcommit()がブロックされ、コミット自体もDOC developer.android.com/reference/を
Chanaka Weerasinghe
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.