OnSavedInstanceState örneği nasıl kullanılır lütfen


110

Konu bir eyaleti kurtarmaya geldiğinde kafam karışıyor. Bu yüzden buna onSaveInstanceState(Bundle)faaliyet yok edilmek üzereyken denildiğini biliyorum . Ancak bilgilerinizi içinde nasıl saklar ve içindeki orijinal durumuna nasıl geri getirirsiniz onCreate(Bundle savedInstanceState)? Bu paketin bilgileri nasıl geri yükleyeceğini anlamıyorum. Birinin bir örnek vermesi faydalı olacaktır. Geliştirici rehberi bunu açıklamak için iyi bir iş çıkarmıyor.

public class Conversation extends Activity {
    private ProgressDialog progDialog;
    int typeBar;
    TextView text1;
    EditText edit;
    Button respond;
    private String name;
    private String textAtView;
    private String savedName;

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

        setContentView(R.layout.dorothydialog);
        text1 = (TextView)findViewById(R.id.dialog);
        edit = (EditText)findViewById(R.id.repsond);
        respond = (Button)findViewById(R.id.button01);

        if(savedInstanceState != null){
            savedInstanceState.get(savedName);
            text1.setText(savedName);
        }
        else{
            text1.setText("Hello! What is your name?");
            respond.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    name = edit.getText().toString();
                    text1.setText("Nice to meet you "+ name);
                }   
            });
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putString(savedName, name);
    }
}

text1.setText (SavedInstanceState.getString (SavedName));
Spidy

@Spidy Peki ya onBackpressed? Buna paketle nasıl tepki verirdim?
tj walker

Yapmazsın. Kullanıcı geri düğmesine bastığında. Aktivite öldürüldü. Kalıcı veri depolaması için bir veritabanı kullanın. Yeniden başlatılan bir uygulamayı önceki durumuna döndürmek için Paketi kullanın.
Spidy

Yanıtlar:


198

BundleKaydetmek istediğiniz tüm bilgiler için bir kapsayıcıdır. İçine veri eklemek için put * işlevlerini kullanırsınız. Veri depolamak için kullanabileceğiniz kısa bir liste (daha fazlası var) Bundle.

putString
putBoolean
putByte
putChar
putFloat
putLong
putShort
putParcelable (used for objects but they must implement Parcelable)

Senin de onCreatefonksiyonda, bu Bundleprograma elle geri döndü. Uygulamanın yeniden yüklenip yüklenmediğini veya ilk kez başlatılıp başlatılmadığını kontrol etmenin en iyi yolu şudur:

if (savedInstanceState != null) {
    // Then the application is being reloaded
}

Verileri geri almak için get * işlevlerini tıpkı put * işlevleri gibi kullanın. Veriler, bir ad-değer çifti olarak saklanır. Bu bir hashmap gibidir. Bir anahtar ve değer sağlarsınız, ardından değeri geri istediğinizde anahtarı verirsiniz ve işlev değeri alır. İşte kısa bir örnek.

@Override
public void onSaveInstanceState(Bundle outState) {
   outState.putString("message", "This is my message to be reloaded");
   super.onSaveInstanceState(outState);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String message = savedInstanceState.getString("message");
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
}

Kaydedilen mesajınız ekrana kızartılacak. Bu yardımcı olur umarım.


14
onSaveInstanceState (), etkinliğiniz duraklatılmadan önce çağrılır. Böylece, potansiyel olarak yok edildikten sonra ihtiyaç duyduğu herhangi bir bilgi, kaydedilen
Paketten

@Spidy Harika! Bir paket hakkındaki her şeyi gerçekten anlamamı sağladın! bu yüzden outState'in SavedInstanceState paketine geri aktarıldığını tahmin ediyorum? Doğru?
tj walker

Evet. OutState Bundle kaydedilen InstanceState Bundle olarak geri verildi
Spidy

1
@tj walker - Diğer bir harika kaynak da teknik referans kitaplarıdır. Pro Android 3, Amazon'da bulabileceğiniz ucuz ama kapsamlı bir kaynak
Spidy

@Spidy Görmeniz için yukarıda etkinlik kodumu gönderdim. Belki de önerdiğiniz gibi, eyaletimi doğru kurtarırsam bana haber verebilirsiniz.
tj walker

34

Tüm yeni Android geliştiricilerinin bilmesi gereken önemli bir not, Widget'lardaki (TextView, Buttons, vb.) Herhangi bir bilginin, onlara bir kimlik atadığınız sürece Android tarafından otomatik olarak saklanacağıdır. Bu, UI durumunun çoğunun sorunsuz bir şekilde halledildiği anlamına gelir. Yalnızca başka verileri depolamanız gerektiğinde bu bir sorun haline gelir.

Gönderen Android Dokümanlar :

Yapmanız gereken tek iş, durumunu kaydetmek istediğiniz her widget için benzersiz bir kimlik (android: id niteliği ile) sağlamaktır. Bir widget'ın kimliği yoksa, durumunu kaydedemez


1
Peki bu gerçekten doğru mu? Çünkü bir düğme metni görüntüleme ve düzenleme metni içeren bir etkinliğim var. Uygulama yok edilirse veya öldürülürse, her şey orijinal durumuna geri döner. Benim uygulamamda textView metinleri kullanıcı butona her tıkladığında değişiyor.
tj walker

Belgeler doğru değil mi? Kendi bilgilerini saklayan bir Görünüm hiç olmadı. Bence en iyi seçeneğiniz, tüm bilgilerinizi kendiniz kaydetmektir.
Spidy

2
Amacınız bilgileri kaydetmekse, bunu yapmak içinSaveInstanceState DEĞİLDİR. Bunun nedeni, çağrılacağına dair hiçbir garanti olmamasıdır (dokümanlara bakınız). Bunun yerine bir veritabanına, SharedPreferences, vb. Yazmalısınız. Evet, bu bilgiler doğrudur. Kullanıcı arayüzünüzün bu şekilde devam edip etmediğini test etmenin en iyi yolu, yön değişiklikleri onCreate'inizi yeniden çalıştırdıkça ekranınızı döndürmek ve durumu geri yüklemek için paketi kullanmaktır.
Keith Adler

@Nissan Fan yukarıda spidy'nin yaptığı gibi bir örnek verebilir misiniz? Paylaşılan referanslar ve tümü ile? Teşekkürler
tj walker

En iyi örnekler açıkçası belgelerden gelmektedir. developer.android.com/guide/topics/data/data-storage.html#pref
Keith Adler

6

İyi bir bilgi: Bundle nesnesinin onCreate () yönteminde boş olup olmadığını kontrol etmenize gerek yoktur. Sistemin onStart () yönteminden sonra çağırdığı onRestoreInstanceState () yöntemini kullanın. Sistem, onRestoreInstanceState () 'i yalnızca geri yüklenecek kaydedilmiş bir durum varsa çağırır, böylece Paketin boş olup olmadığını kontrol etmenize gerek yoktur.


5

Bilgi depola:

static final String PLAYER_SCORE = "playerScore";
static final String PLAYER_LEVEL = "playerLevel";

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(PLAYER_SCORE, mCurrentScore);
    savedInstanceState.putInt(PLAYER_LEVEL, mCurrentLevel);

// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}

OnCreate-Method'unuzdaki bilgileri geri yüklemek istemiyorsanız:

İşte örnekler: Bir Aktiviteyi Yeniden Oluşturma

OnCreate () sırasında durumu geri yüklemek yerine, sistemin onStart () yönteminden sonra çağırdığı onRestoreInstanceState () uygulamasını uygulamayı seçebilirsiniz. Sistem, onRestoreInstanceState () 'i yalnızca geri yüklenecek kaydedilmiş bir durum varsa çağırır, böylece Paketin boş olup olmadığını kontrol etmenize gerek yoktur.

public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);

// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(PLAYER_SCORE);
mCurrentLevel = savedInstanceState.getInt(PLAYER_LEVEL);
}

0

Temel olarak onSaveInstanceState (Bundle outBundle) size bir paket verecektir. Bundle sınıfına baktığınızda, içine birçok farklı şey koyabileceğinizi göreceksiniz. Bir sonraki onCreate () çağrısında, bu Paketi bir argüman olarak geri alırsınız. Ardından değerlerinizi tekrar okuyabilir ve aktivitenizi geri yükleyebilirsiniz.

EditText ile bir etkinliğiniz olduğunu varsayalım. Kullanıcı içine bir metin yazdı. Bundan sonra sistem onSaveInstanceState () i çağırır. Metni EditText'ten okursunuz ve Bundle.putString ("edit_text_value", theValue) yoluyla Bundle'a yazarsınız.

Şimdi onCreate çağrılıyor. Verilen paketin boş olup olmadığını kontrol edin. Durum buysa, değerinizi Bundle.getString ("edit_text_value") aracılığıyla geri yükleyebilir ve EditText'inize geri koyabilirsiniz.


0

Bu ek bilgi içindir.

Bu senaryoyu hayal edin

  1. AktiviteA AktiviteB'yi başlatır.
  2. ActivityB yeni bir ActivityAPrime başlatır.

    Intent intent = new Intent(getApplicationContext(), ActivityA.class);
    startActivity(intent);
  3. ActivityAPrime'ın ActivityA ile hiçbir ilişkisi yoktur.
    Bu durumda ActivityAPrime.onCreate () içindeki Paket boş olacaktır.

ActivityA ve ActivityAPrime farklı etkinlikler yerine aynı etkinlik olacaksa, ActivityB, startActivity () kullanmak yerine finish () öğesini çağırmalıdır.


açıklığa kavuşturmak gerekirse, örneğinizde ActivityA == ActivityA instance 1 ve ActivityAPrime == ActivityA instance 2 mi? ayrıca, "ActivityB, startActivity () kullanmaktan çok finish () 'yi çağırmalıdır." Şunu mu demek istiyorsun: (1) AcitivityB, finish () 'yi çağırmalı ve sonra startActivity () kullanmalı (2) veya ActivityB, startActivity () kullanmak yerine finish () çağırmalı mı? 2. seçeneği kastettiyseniz, yok edilmeden / bitirilmeden önce içerdiği verileri yükleyebilmeniz için birisinin aynı activityA örnek1'i yeniden başlatmasını nasıl önerirsiniz? Teşekkürler
cjayem13

ActivityA ve ActivityAPrime aynı sınıftadır ancak farklı örneklerdir. Bu senaryoda, ActivityA henüz işini bitirmedi, ortasında, ActivityB'yi yarattı ve başlattı, bu nedenle ActivityB bittiğinde, ActivityA kalan işine devam etmelidir. Bu durumda startActivity'yi çağırmak ve ActivityA ile ActiviyAPrime'ın aynı örnek olmasını beklemek yanlıştır. bu yüzden ActivityA'yı yeniden başlatmamalıyız, sadece ActivityB'yi bitirip ActivityA'nın
ken

0

Veriler Şuradan Yüklenmezse savedInstanceStateaşağıdaki kodu kullanın.
Sorun url çağrısının tam olarak tamamlanmamasıdır, bu nedenle verilerin yüklenip yüklenmediğini kontrol edin ve ardından instanceState değerini gösterin.

//suppose data is not Loaded to savedInstanceState at 1st swipe
if (savedInstanceState == null && !mAlreadyLoaded){
    mAlreadyLoaded = true;
    GetStoryData();//Url Call
} else {
    if (listArray != null) {  //Data Array From JsonArray(ListArray)
        System.out.println("LocalData  " + listArray);
        view.findViewById(R.id.progressBar).setVisibility(View.GONE);
    }else{
        GetStoryData();//Url Call
    }
}
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.