SharedPreferences içindeki commit () ve cameram () arasındaki fark nedir


431

Ben kullanıyorum SharedPreferencesbenim android app. Her ikisini de commit()ve apply()paylaşılan tercih yöntemini kullanıyorum . AVD 2.3 kullandığımda hiçbir hata göstermiyor, ancak kodu AVD 2.1'de çalıştırdığımda apply()yöntem hata gösteriyor.

Peki bu ikisi arasındaki fark nedir? Ve sadece kullanarak commit()tercih değerini herhangi bir sorun olmadan saklayabilir miyim?


115
Bu bir yaşında, ama yine de üzerinde yorum yapacağım, her ne kadar açık olsa da, cevapların hiçbiri bu noktayı apply()belirtmiyor : senkronize olmayan bir şekilde disk I / O yapacak commit(). Bu yüzden gerçekten commit()UI iş parçacığından aramamalısınız.
michiakig

Birden fazla SharedPreferences.Editor nesnesi kullanıldığında, son çağrılacak olan apply()kazanır. Bu nedenle, kullanabileceğiniz apply()yerine commit()Emin tek SharedPreferences.Editor uygulamanız tarafından kullanılıyor yaparsanız güvenle.
aoeu

2
Android Studio Lint uyarısına göre: commit () verileri anında ve senkronize olarak kaydeder. Ancak, Apply () işlevi eşzamansız olarak (arka planda) kaydeder ve böylece bazı performansı iyileştirir. Bu nedenle, dönüş türünü önemsemiyorsanız, (veri başarıyla kaydedilip kaydedilmediyse) commit () yerine, () tercih edilir.
Rahul Raina

Lint uyarısını kullanırken devre dışı bırakmanın bir yolu var mı commit()?
QED

Yanıtlar:


653

apply()2.3 ilave edildi, bu taahhüt olmadan başarılı veya başarısız gösteren bir boolean döndüren.

commit()kaydetme çalışırsa true değerini, aksi halde false değerini döndürür .

apply() Android dev ekibi neredeyse hiç kimsenin dönüş değerini fark etmediğini fark ettiğinden, eşzamansız olduğundan uygulama daha hızlıdır.

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


8
Bu cevap doğru ama sanırım yukarıdaki @spacemanaki'nin yorumu da doğru bilgiler içeriyor
Aksel Fatih

58
commit (), verilerini derhal kalıcı depolamaya yazar. Uygula () ise arka planda işler.
capt.swag

18
bir yarış durumu yaratıyor mu?
ChrisMcJava

42
Apply () ile bir şeyler yazar ve hemen sonra okumaya çalışırsam ne olur? Okumanın bana en yeni değeri vereceği garanti ediliyor mu? Belgeler, fire () uygulandıktan sonra başka bir command () gerçekleşirse, exec () işlevi diske kalıcı oluncaya kadar engellenir, bu da 'yazma' işlemleri söz konusu olduğunda bu sorunun oluşmadığını açıkça gösterir. , ama hemen sonra yazıyor ve okuyorsanız ne olacak? Testlerimden, en yeni değer döndürülür, ancak bunun% 100 garantili olup olmadığını bilmek istiyorum.
Tiago

22
commit () öğesinin herhangi bir kısmını uygula () ile değiştirmek güvenlidir bkz. developer.android.com/reference/android/content/…
Tigran Sarkisian

221

tl; dr:

  • commit()verileri eşzamanlı olarak yazar (çağrısının iş parçacığını engeller). Daha sonra operasyonun başarısı hakkında sizi bilgilendirir .
  • apply()verilerin eşzamansız olarak yazılmasını zamanlar . O bilgilendirmek gelmez operasyonun başarısı hakkında.
  • Herhangi bir getX yöntemiyle kaydeder apply()ve hemen okursanız , yeni değer döndürülür!
  • Bir apply()noktada aradıysanız ve hala yürütülüyorsa, commit()yapılacak tüm çağrılar ve tüm geçerli çağrılar bitinceye kadar yapılacak çağrılar engellenir .

Dan daha çok derinlemesine bilgi SharedPreferences.Editor Belgeleri:

Tercihlerini kalıcı depolama alanına eşzamanlı olarak yazan commit () 'dan farklı olarak , Apply (), bellek içi SharedPreferences'daki değişikliklerini hemen yapar, ancak diske eşzamansız bir taahhüt başlatır ve herhangi bir hata bildirilmez . Bu SharedPreferences üzerindeki başka bir düzenleyici, bir application () hala göze çarpıyorken normal bir command () yaparsa, commit () tüm asenkron taahhütler tamamlanıncaya kadar kendisi de bloke olur.

SharedPreferences örnekleri bir işlem içindeki tekil öğeler olduğundan, döndürme değerini zaten yoksayıyorsanız, herhangi bir exec () örneğini application () ile değiştirmek güvenlidir.

SharedPreferences.Editor arabiriminin doğrudan uygulanması beklenmez. Ancak, daha önce uyguladıysanız ve şu anda eksik Apply () ile ilgili hatalar alıyorsanız, commit () 'dan ()' dan çağrı yapabilirsiniz.


19
Bu çok daha iyi bir cevaptır çünkü apply()asenkron ve beklemede olan yazarlar gelecekteki çağrıları engeller commit().
spaaarky21

22

Uygula () yerine command () kullanarak bazı sorunlar yaşıyorum. Daha önce diğer yanıtlarda belirtildiği gibi, Apply () yöntemi eşzamansızdır. "Dize kümesi" tercihi için oluşturulan değişiklikler asla kalıcı belleğe yazılmış sorun alıyorum.

Programın "gözaltına alınmasını" veya Android 4.1 ile cihazımda kurduğum ROM'da, bellek gereksinimleri nedeniyle işlem sistem tarafından öldürüldüğünde gerçekleşir.

Tercihlerinizin canlı olmasını istiyorsanız "commit ()" yerine "Apply ()" kullanmanızı öneririm.


Eşzamanlı iş parçacığı nedeniyle sorununuzun ilişkili olmadığından emin misiniz? Uygula () gönderdikten sonra, eklediğiniz şeyleri okumak için bir süre beklemeniz gerekir, aksi takdirde UI iş parçacığı, uygulayıcı () iş parçacığı değişiklikleri gerçekleştirmeden önce okumaya çalışır.
Marco Altran

Dize seti ile ilgili olarak, stackoverflow.com/questions/16820252/…
Tapirboy

@JoseLSegura - dokümanlar aksini öneriyor: developer.android.com/intl/ja/reference/android/content/… "Android bileşen yaşam döngüleri ve bunların diske uygula () yazma ile etkileşimleri hakkında endişelenmenize gerek yok. durumları değiştirmeden önce uçuş sırasındaki diskin Apply () öğesinden tamamlandığından emin olur. " Gördüğünüz şeyin Android'de bir hata olup olmadığını ve yeni sürümlerde düzeltilip düzeltilmediğini merak ediyorum.
ToolmakerSteve

Aynı sorun benim app sıfırlamak için kütüphane "ProcessPhoenix" kullanarak bana oldu. Bir sıfırlama gerçekleştirmeden hemen önce bir tercih kaydediyordum ve "uygula" çalışmıyor.
ElYeante

14

Uygula () kullanın.

Değişiklikleri hemen RAM'a yazar ve bekler ve daha sonra dahili depolamaya (gerçek tercih dosyası) yazar. Tamam, değişiklikleri senkronize ve doğrudan dosyaya yazar.


14
  • commit()senkronize, apply()senkronize değil

  • apply() void fonksiyonudur.

  • commit() yeni değerler kalıcı depolama alanına başarıyla yazıldıysa true değerini döndürür.

  • apply() durumları değiştirmeden önce garantiler tamamlandı, Android bileşen yaşam döngüleri hakkında endişelenmenize gerek yok

Döndürülen değeri commit()kullanmazsanız commit()ve ana iş parçacığından kullanıyorsanız apply(), commit()


13

Dokümanlar apply()ve arasındaki farkın oldukça iyi bir açıklamasını verir commit():

commit()Tercihlerini kalıcı depolama alanına eşzamanlı olarak yazan programın aksine , apply()değişikliklerini SharedPreferencesanında bellek içi olarak yapar, ancak diske eşzamansız bir taahhüt başlatır ve herhangi bir hata bildirilmez. Bu konuda başka bir editör, a hala olağanüstü bir durumdaysa SharedPreferencesdüzenli commit()bir apply()işlem yaparsa , commit()tüm eşzamansız işlemlerin yanı sıra taahhüdün kendisi tamamlanıncaya kadar engeller. Gibi SharedPreferencesörnekler bir süreç içinde singletons vardır, bu herhangi bir örneğini değiştirmek için güvenli commit()ile apply()zaten dönüş değeri gözardı olsaydı.


6

Javadoc'tan:

Tercihlerini kalıcı depolama alanına eşzamanlı olarak yazan commit () 'dan farklı olarak, Apply (), bellek içi SharedPreferences'daki değişikliklerini hemen yapar, ancak diske eşzamansız bir taahhüt başlatır ve herhangi bir hata bildirilmez. Bu SharedPreferences üzerindeki başka bir düzenleyici, bir> Apply () hala göze çarpıyorken düzenli bir kesinleştirme () yaparsa, tüm asenkron taahhütler tamamlanıncaya kadar taahhüt tamamlanana kadar commit () engellenir


1

Commit () ve Apply () arasındaki fark

SharedPreference'ı kullanırken bu iki terimle kafamızı karıştırabiliriz. Temel olarak muhtemelen aynıdırlar, bu yüzden commit () ve Apply () arasındaki farkları açıklığa kavuşturalım.

1. dönüş değeri:

apply()başarı veya başarısızlık gösteren bir boole döndürmeden teslim eder. commit() kaydetme işe yararsa true değerini, aksi halde false değerini döndürür.

  1. hız:

apply()daha hızlı. commit()daha yavaştır.

  1. Eşzamansız ve Eşzamanlı:

apply(): Eşzamansız commit(): Eşzamanlı

  1. atom:

apply(): atom commit(): atom

  1. Hata bildirimi:

apply(): Hayır commit(): Evet


apply()"Daha hızlı" nasıl commit()? Esasen ipliğin Looper'ına konacak aynı görevi temsil ederler. arka planda commit()alırken bu görevi apply()ana İlmek Yapıcıya koyar , böylece ana ileticiyi disk G / Ç görevinden uzak tutar.
Taseer

Tercihlerini kalıcı depolama alanına eşzamanlı olarak yazan commit () 'dan farklı olarak, Apply (), bellek içi SharedPreferences'daki değişikliklerini hemen yapar, ancak diske eşzamansız bir taahhüt başlatır ve herhangi bir hata bildirilmez. Bu SharedPreferences üzerindeki başka bir düzenleyici, bir application () hala göze çarpıyorken düzenli bir kesinleştirme () yaparsa, tüm uyumsuzluk işlemleri tamamlanana kadar ve kesinleştirme kendisi de DOC'yi görene kadar commit () engellenir developer.android.com/reference/ android / içerik /…
Chanaka Weerasinghe
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.