2013-05-27 11 views
33

Próbuję zapisać dane w różnych zmianach orientacji. Jak pokazano w poniższym kodzie, używam onSaveInstanceState() i onRestoreInstanceState(). Próbuję uzyskać zapisaną wartość i sprawdzam, czy jest to poprawna wartość w onRestoreInstanceState(). Ale kiedy próbuję użyć nowej wartości w onCreate(), nie mam nowej wartości, ale starej.Jak korzystać z metody onSaveInstanceState() i onRestoreInstanceState()?

protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putString("TEXT", user); 

    } 
protected void onRestoreInstanceState(Bundle savedInstanceState) { 
    super.onRestoreInstanceState(savedInstanceState); 
    savedUser = savedInstanceState.getString("TEXT"); 
    Log.d("enregistred value", savedUser); 

} 



public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     int display_mode = getResources().getConfiguration().orientation; 

     if (display_mode == 1) { 

      setContentView(R.layout.main_grid); 
      mGrid = (GridView) findViewById(R.id.gridview); 
      mGrid.setColumnWidth(95); 
      mGrid.setVisibility(0x00000000); 
      // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 

     } else { 
      setContentView(R.layout.main_grid_land); 
      mGrid = (GridView) findViewById(R.id.gridview); 
      mGrid.setColumnWidth(95); 
      Log.d("Mode", "land"); 
      // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 

     } 
     Log.d("savedUser", savedUser); 
     if (savedUser.equals("admin")) { //value 0 
      adapter.setApps(appManager.getApplications()); 
     } else if (savedUser.equals("prof")) { //value 1 
      adapter.setApps(appManager.getTeacherApplications()); 
     } else {// default value 
      appManager = new ApplicationManager(this, getPackageManager()); 
      appManager.loadApplications(true); 
      bindApplications(); 
     } 
} 
+1

możliwe duplikat [onSaveInstanceState() i onRestoreInstanceState()] (http://stackoverflow.com/ pytania/4096169/onsaveinstancestate-and-onrestoreinstancestate) –

Odpowiedz

15
  • onSaveInstanceState() to metoda używana do przechowywania danych przed wstrzymaniem działalności.

Opis haka umożliwiając w celu generowania reprezentacji stanie wewnętrznego, który może być następnie używany do tworzenia nowego wystąpienia w tym samym stanie. Ten stan powinien zawierać tylko te informacje, które nie są trwałe lub nie mogą być później odtworzone. Na przykład, nigdy nie będziesz przechowywać aktualnej pozycji na ekranie, ponieważ zostanie ona obliczona ponownie, gdy nowa instancja widoku zostanie umieszczona w jego hierarchii widoku.

  • onRestoreInstanceState() to metoda używana do odzyskania tych danych.

Opis Ta metoda nazywa się po onStart(), gdy prowadzona jest ponownie inicjalizowana z wcześniej zapisanego stanu, podane tu w savedInstanceState. Większość implementacji po prostu użyje polecenia onCreate (Bundle), aby przywrócić ich stan, ale czasami wygodnie jest to zrobić tutaj, po wykonaniu całej inicjalizacji lub zezwoleniu subklasom na podjęcie decyzji, czy użyć domyślnej implementacji. Domyślna implementacja tej metody wykonuje przywracanie dowolnego stanu widoku, który został wcześniej zamrożony przez onSaveInstanceState (pakiet).

Rozważmy następujący przykład tutaj:
Ty aplikacja ma 3 pola edycji, gdzie użytkownik było wprowadzenie w niektórych informacji, ale on dzwoni więc jeśli nie korzystać z powyższych metod, co wszyscy wszedł zostaną utracone.
Zawsze więc zapisz bieżące dane w metodzie aktywności onPause() jako pakiecie & w metodzie onResume() wywołanie metody onRestoreInstanceState().

proszę zobaczyć:

How to use onSavedInstanceState example please

http://www.how-to-develop-android-apps.com/tag/onrestoreinstancestate/

+0

czy możesz podać mi przykład, proszę. Ponieważ wiem, że kiedy zmieniam orientację, dzwonię do "Przeszkody", a następnie "Wskrzesz", więc jak mogę użyć zaoszczędzonej wartości w Oncreat. – Zizou

+0

Proszę zobaczyć powyższe linki –

+1

Czy na pewno chcesz zapisać tekst w polach edycji? Dokument mówi: "Domyślna implementacja zajmuje się większości stanów interfejsu użytkownika dla każdej instancji przez wywołanie metody onSaveInstanceState() w każdym widoku hierarchii, który ma identyfikator ..." –

35

Gdy działalność jest odtworzone po tym jak został wcześniej zniszczony, można odzyskać zapisany stan z Bundle, że system przechodzi swoje czynność. Obie metody wywołania zwrotnego onCreate() i onRestoreInstanceState() otrzymują tę samą wiązkę, która zawiera informacje o stanie instancji instancji.

Ponieważ metoda onCreate() jest wywoływana, czy system jest tworzenie nową instancję swojej działalności lub odtworzenie poprzedni, trzeba sprawdzić, czy Bundle stan jest zerowy przed przystąpieniem do lektury. Jeśli wartość jest pusta, system tworzy nowe wystąpienie z działalnością zamiast przywracania poprzedniej, która została zniszczona.

static final String STATE_USER = "user"; 
private String mUser; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // Check whether we're recreating a previously destroyed instance 
    if (savedInstanceState != null) { 
     // Restore value of members from saved state 
     mUser = savedInstanceState.getString(STATE_USER); 
    } else { 
     // Probably initialize members with default values for a new instance 
     mUser = "NewUser"; 
    } 
} 

@Override 
public void onSaveInstanceState(Bundle savedInstanceState) { 
    savedInstanceState.putString(STATE_USER, mUser); 
    // Always call the superclass so it can save the view hierarchy state 
    super.onSaveInstanceState(savedInstanceState); 
} 

http://developer.android.com/training/basics/activity-lifecycle/recreating.html

+2

Próbowałem tego, ale mój crash aplikacji. – Zizou

+0

@DataDino Dokumentacja powiązana z odpowiedzią Arvisa pokazuje, że super wywołanie przechodzi wzdłuż zapisanego pakietu instancji przez wywołanie super ostatniego. Jeśli wywołasz super super pierwszy, zostawisz stan instancji jako kopię pakietu po zakończeniu wywołania procedury, bez żadnych danych przekazanych do instancji działania. Java jest według wartości, a nie jako odniesienie. :) Bardzo trudna lekcja, której nauczyłem się pochodząc z .NET. – DoctorD

+0

@DoctorD, Whoops! Masz rację. Obwiniam to na brak kofeiny. – DataDino

9

Dzieje się tak dlatego, że używasz savedValue w metodzie onCreate(). savedValue jest aktualizowany w metodzie onRestoreInstanceState(), ale onRestoreInstanceState() jest wywoływany po metodzie onCreate(). Można:

  1. Aktualizacja metoda savedValue w onCreate() lub
  2. Przenoszenie kodu, które wykorzystują nową savedValue w onRestoreInstanceState() metody.

Ale proponuję użyć pierwsze podejście, dzięki czemu kod tak:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    int display_mode = getResources().getConfiguration().orientation; 

    if (display_mode == 1) { 

     setContentView(R.layout.main_grid); 
     mGrid = (GridView) findViewById(R.id.gridview); 
     mGrid.setColumnWidth(95); 
     mGrid.setVisibility(0x00000000); 
     // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 

    } else { 
     setContentView(R.layout.main_grid_land); 
     mGrid = (GridView) findViewById(R.id.gridview); 
     mGrid.setColumnWidth(95); 
     Log.d("Mode", "land"); 
     // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 

    } 
    if (savedInstanceState != null) { 
     savedUser = savedInstanceState.getString("TEXT"); 
    } else { 
     savedUser = "" 
    } 
    Log.d("savedUser", savedUser); 
    if (savedUser.equals("admin")) { //value 0 
     adapter.setApps(appManager.getApplications()); 
    } else if (savedUser.equals("prof")) { //value 1 
     adapter.setApps(appManager.getTeacherApplications()); 
    } else {// default value 
     appManager = new ApplicationManager(this, getPackageManager()); 
     appManager.loadApplications(true); 
     bindApplications(); 
    } 
} 
Powiązane problemy