2012-04-17 21 views
17

Próbuję zaktualizować wartości SharedPreferences, tutaj jest mój kod:SharedPreferences nie jest aktualizowana

edit = PreferenceManager.getDefaultSharedPreferences(this).edit(); 
edit.putString(Settings.PREF_USERNAME+"",txtuser); 
edit.putString(Settings.PREF_PASSWORD+"",txtpass); 
edit.commit();" 

Problem polega na tym, że kiedy mam dostępu do tej wartości, to nie wraca zaktualizowane wartości, daje mi wartość SharedPreferences.

Ale kiedy potwierdzam dane w pliku XML, dane aktualizowane w tym.

Po ponownym uruchomieniu aplikacji otrzymuję zaktualizowane wartości. Wymaga to ponownego uruchomienia aplikacji, aby uzyskać zaktualizowane wartości.
Jak uzyskać zaktualizowane wartości po zmianie?

góry dzięki

Oto cały mój kod:

@Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.main); 
     ctx=this; 

      status=PreferenceManager.getDefaultSharedPreferences(this).getString(Settings.PREF_STATUS, Settings.DEFAULT_STATUS);// get old value 
     submit.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

        on(ctx,true);// function will call and value is updated 

       } 
      }});  

    status=PreferenceManager.getDefaultSharedPreferences(this).getString(Settings.PREF_STATUS, Settings.DEFAULT_STATUS);// this should give me a updated value but gives old value 

    } 
    public static boolean on(Context context) { 
     return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(Settings.PREF_ON, Settings.DEFAULT_ON); 
    } 

    public static void on(Context context,boolean on) { 
      if (on) Receiver.engine(context).isRegistered(); // 
     } 




**********in reciver file*********** 
public void isRegistered) { 
     Editor edit = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).edit(); 
     edit.putString(Settings.PREF_STATUS+"","0"); 
     edit.commit(); 
} 
+1

pokaż kod uzyskania wartości. –

+0

Czy możesz pokazać inny kod, który podaje prawidłowe wartości. A skąd aktualizujesz wartości? Jeśli otrzymujesz wartości przed aktualizacją preferencji współdzielonych, na pewno podasz stare wartości. –

Odpowiedz

62

Zamiast edit.commit();, należy użyć edit.apply();. Zastosuj natychmiast zaktualizuje obiekt preferencji i zapisze nowe wartości asynchronicznie, dzięki czemu można odczytać najnowsze wartości.


commit()

Commit preferencje zmienia się z powrotem z tego edytora do SharedPreferences obiekt jest edycja. Atomowo wykonuje żądane modyfikacje, zastępując to, co aktualnie jest w obiektach SharedPreferences .

Należy zauważyć, że gdy dwaj redaktorzy modyfikują preferencje w tym samym czasie, ostatni wywołujący zatwierdzenie wygrywa.

Jeśli nie zależy Ci na wartości zwracanej i używasz jej z głównego wątku aplikacji, rozważ użycie opcji apply().

zastosowanie()

Commit preferencje zmienia się z powrotem z tego edytora do SharedPreferences obiekt jest edycja. Atomowo wykonuje żądane modyfikacje, zastępując to, co aktualnie jest w obiektach SharedPreferences .

Należy pamiętać, że gdy dwóch redaktorów modyfikuje preferencje w tym samym czasie, wygrywa ostatnie z nich, do którego należy zadzwonić.

przeciwieństwie commit(), który pisze swoje preferencje się do uporczywego przechowywania synchronicznie, apply() zobowiązuje się do jego zmiany do SharedPreferences bezpośrednio w pamięci, ale zaczyna asynchroniczny zobowiązać się do dysku i nie zostanie powiadomiony o wszelkie awarie. Jeśli inny edytor na to SharedPreferences robi zwykły commit(), podczas gdy apply() jest nadal zaległe, commit() będzie blokować dopóki wszystkie asynchroniczne zatwierdzenia nie zostaną zakończone, jak również samo zatwierdzenie.

Ponieważ wystąpienia SharedPreferences są pojedynczymi pojedynczymi procesami w ramach procesu, można je bezpiecznie zastąpić każdą instancję commit() za pomocą apply(), jeśli wcześniej ignorowano wartość zwracaną przez parametr .

Nie musisz martwić się o cykl życia składników systemu Android i ich interakcję z pisaniem apply() na dysk. Struktura zapewnia, że ​​zapisywanie dysku w locie z funkcji apply() zostanie zakończone przed przełączeniem stanów.

+1

Wprawdzie apply() jest dobrą alternatywą, ale wprowadza kwestię konieczności ustawienia min API na 9 (2,3 Gingerbread), który według aktualnych statystyk unieważnia około 30% wszystkich urządzeń z Androidem.Zauważyłem, że commit() działa tak długo, jak przy następnym sprawdzaniu tworzysz nową instancję obiektu SharedPreferences, która może nie być trudną zmianą kodu – Jag

+0

jeśli 'apply()' jest asynchronicznie nazywane, dlaczego czytam najnowsza wartość, jeśli ten kod? https://gist.github.com/anonymous/62637e408baf273a7bc43754422c3739 –

+0

@MaksimDmitriev "apply() natychmiast zatwierdza swoje zmiany w pamięci SharedPreferences w pamięci, ale uruchamia asynchroniczne zatwierdzenie na dysk i nie będziesz powiadamiany o żadnych błędach." Gdy czytasz ze współdzielonych preferencji natychmiast po umieszczeniu wartości i zastosowaniu jej, informuje wartość z pamięci, a nie z pamięci. – cuddlecheek

1

Spróbuj tak,

public SharedPreferences prefs; 
SharedPreferences.Editor editor = prefs.edit(); 
editor.putString(Settings.PREF_USERNAME+"", txtuser); 
editor.putString(Settings.PREF_PASSWORD+"", entered_name); 
editor.commit();  
1

nadzieję, że to pomoże ..

SharedPreferences mypref = PreferenceManager.getDefaultSharedPreferences(this); 
SharedPreferences.Editor prefsEditr = mypref.edit(); 
prefsEditr.putString("Userid", UserId); 
prefsEditr.commit(); 


String task1 = mypref.getString("Userid", ""); 
1

Spróbuj ten kod:

SharedPreferences edit = PreferenceManager.getDefaultSharedPreferences(this); 
SharedPreferences.Editor editor1 = edit.edit(); 
editor.putString(Settings.PREF_USERNAME + "", txtuser); 
editor.putString(Settings.PREF_PASSWORD + "", entered_name); 
editor.commit(); 
0

Cóż, nawet jeśli moja odpowiedź nadeszła 3 lata po pytaniu, mam nadzieję, że to pomoże. Problem nie pochodzi z zatwierdzenia lub zastosowania, ale ze struktury kodu.

Wyjaśnijmy: na smartfonie uruchamiasz aplikację, ale nie opuszczasz aplikacji tak, jak robimy to na komputerach. Oznacza to, że po powrocie do menu smartfona, aplikacja nadal działa. Kiedy klikniesz ponownie na ikonę APP, nie uruchomisz ponownie aplikacji, ale po prostu ją obudzisz. W zgrabnym kodzie widzimy, że dzwoni on do GetDefaultSharedPreferences w jego funkcji Create.

Dlatego nazywa się getDefaultSharedPreferences, gdy uruchamia aplikację po raz pierwszy. Ale kiedy ustawia aplikację na tle, a następnie budzi aplikację, połączenie nie jest wykonywane.

Miałem ten sam problem: Sprawdzam, czy mam SharedPreference dla mojej aplikacji. Jeśli nie, pytam o formularz, aby poprosić użytkownika o podanie wartości. Jeśli tak, sprawdzam datę preferencji. Jeśli jest zbyt stary, pytam o formularz. Po formularzu zapisuję preferencje z bieżącą datą. Zauważyłem, że test o istnieniu SharedPreference (który został ustawiony w tym samym miejscu, co połączenie) został wykonany tylko przy pierwszym uruchomieniu aplikacji, ale nie po obudzeniu APP. Oznacza to, że nie byłem w stanie sprawdzić limitu czasu w moich SharedPreferences!

Jak rozwiązać ten problem? Wystarczy dodać:

  @Override 
      public void onResume(){ 
      super.onResume(); 
     // And put the SharedPreferences test here 
      } 

Ten kod zostanie wywołana przy pierwszym uruchomieniu APP ale też za każdym razem użytkownik obudzić go.

Powiązane problemy