कृपया onSavedInstanceState उदाहरण का उपयोग कैसे करें


110

जब मैं किसी राज्य को बचाने के लिए नीचे आता हूं तो मैं भ्रमित होता हूं। तो मुझे पता है कि onSaveInstanceState(Bundle)कहा जाता है जब गतिविधि नष्ट होने वाली होती है। लेकिन आप इसमें अपनी जानकारी को कैसे संग्रहीत करते हैं और इसे अपनी मूल स्थिति में वापस लाते हैं onCreate(Bundle savedInstanceState)? मुझे समझ नहीं आ रहा है कि यह बंडल जानकारी को कैसे पुनर्स्थापित करेगा। यह उपयोगी होगा यदि कोई एक उदाहरण प्रदान कर सकता है। देव गाइड इसे समझाने का अच्छा काम नहीं करता है।

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));
स्पिक

@ सक्रिय ऑनबैक्ड के बारे में क्या? मैं बंडल के साथ इस पर कैसे प्रतिक्रिया करूंगा?
tj वॉकर

आप नहीं करेंगे। जब उपयोगकर्ता बैक बटन दबाता है। गतिविधि को मार दिया जाता है। स्थायी डेटा संग्रहण के लिए डेटाबेस का उपयोग करें। अपनी पिछली स्थिति में पुनरारंभ किए गए एप्लिकेशन को वापस करने के लिए बंडल का उपयोग करें।
स्पिक

जवाबों:


198

Bundleसभी जानकारी आप सहेजना चाहते हैं के लिए एक कंटेनर है। आप इसमें डेटा डालने के लिए पुट * फंक्शन्स का उपयोग करते हैं। यहाँ एक छोटी सूची है (पुट फ़ंक्शंस की) जो आप डेटा को स्टोर करने के लिए उपयोग कर सकते हैं Bundle

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

आपके onCreateफ़ंक्शन में, यह Bundleप्रोग्राम को वापस सौंप दिया गया है। यह जांचने का सबसे अच्छा तरीका है कि क्या एप्लिकेशन पुनः लोड किया जा रहा है, या पहली बार शुरू किया गया है:

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

डेटा वापस लाने के लिए, पुट * फंक्शन्स की तरह ही * फ़ंक्शंस का उपयोग करें। डेटा को नाम-मूल्य जोड़ी के रूप में संग्रहीत किया जाता है। यह हैशमैप की तरह है। आप एक कुंजी और मूल्य प्रदान करते हैं, फिर जब आप मूल्य वापस चाहते हैं, तो आप कुंजी देते हैं और फ़ंक्शन को मान मिलता है। यहाँ एक छोटा उदाहरण है।

@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();
    }
}

आपके सहेजे गए संदेश को स्क्रीन पर टोस्ट किया जाएगा। उम्मीद है की यह मदद करेगा।


14
आपकी गतिविधि रुकने से पहले onSaveInstanceState () को कॉल किया जाता है। संभावित रूप से नष्ट हो जाने के बाद इसे नष्ट होने से बचाने वाली किसी भी जानकारी को सहेजे गए बंडल से प्राप्त किया जा सकता है
Diederik

@ बहुत बढ़िया! आपने अभी-अभी मुझे एक बंडल के बारे में सब कुछ समझा दिया है! इसलिए im अनुमान लगा रहा है कि स्टेस्ट वापस बचा गया है। InstanceState बंडल? सही बात?
tj वाकर

हां। OutState बंडल को SaveInstanceState बंडल
Spidy

1
@tj वाकर - एक और महान संसाधन तकनीकी संदर्भ पुस्तकें हैं। प्रो एंड्रॉइड 3 एक सस्ता लेकिन व्यापक संसाधन है जिसे आप अमेज़ॅन
स्पिड

@Spidy मैंने आपको देखने के लिए ऊपर अपना गतिविधि कोड पोस्ट किया है। शायद आप मुझे बता सकते हैं कि क्या im मेरे राज्य को बचाने का अधिकार है, जैसा कि आपने सुझाव दिया था।
tj वाकर

34

एक प्रमुख नोट जो सभी नए एंड्रॉइड डेवलपर्स को पता होना चाहिए कि जब तक आप उन्हें एक आईडी असाइन करते हैं, तब तक विजेट (टेक्स्ट व्यू, बटन, आदि) में कोई भी जानकारी स्वचालित रूप से एंड्रॉइड द्वारा बनी रहेगी। तो इसका मतलब है कि अधिकांश यूआई स्थिति को बिना किसी समस्या के ध्यान में रखा गया है। केवल जब आपको अन्य डेटा संग्रहीत करने की आवश्यकता होती है, तो यह एक मुद्दा बन जाता है।

से एंड्रॉयड डॉक्स :

आपके द्वारा आवश्यक एकमात्र कार्य प्रत्येक विजेट के लिए एक अद्वितीय आईडी (एंड्रॉइड: आईडी विशेषता के साथ) प्रदान करना है जिसे आप अपनी स्थिति को सहेजना चाहते हैं। यदि किसी विजेट के पास आईडी नहीं है, तो वह अपनी स्थिति नहीं बचा सकता है


1
खैर क्या यह सच है? क्योंकि मेरे पास एक बटन टेक्स्टव्यू और संपादित पाठ के साथ एक गतिविधि है। यदि एप्लिकेशन नष्ट हो जाता है या मारा जाता है तो सब कुछ अपनी मूल स्थिति में वापस आ जाता है। मेरे आवेदन में टेक्स्टव्यू टेक्स्ट हर बार उपयोगकर्ता को बटन क्लिक करने पर बदलता है।
tj वाकर

क्या दस्तावेज गलत है? मेरे पास अपनी जानकारी सहेजने का दृश्य कभी नहीं था। आपकी सबसे अच्छी शर्त यह है कि आप मेरी राय में अपनी सारी जानकारी खुद ही सहेज लें।
स्पिक

2
यदि आपका लक्ष्य onSaveInstanceState जानकारी सहेजना है, तो ऐसा करने का स्थान नहीं है। ऐसा इसलिए है क्योंकि इसकी कोई गारंटी नहीं है कि इसे कहा जाएगा (डॉक्स देखें)। आपको इसके बजाय एक डेटाबेस, शेयर्डप्रिफरेंस आदि को लिखना चाहिए, हाँ यह जानकारी सटीक है। यह परीक्षण करने का सबसे अच्छा तरीका है कि यदि आपका UI इस तरह से जारी है, तो अपने प्रदर्शन को घुमाएं क्योंकि ओरिएंटेशन आपके ऑनक्रिएट को बदल देता है और राज्य को पुनर्स्थापित करने के लिए बंडल का उपयोग करता है।
कीथ एडलर

@ निसान फैन क्या आप एक उदाहरण दे सकते हैं जैसा कि स्पाइडी ने ऊपर किया था? Shareprefs और सभी के साथ? धन्यवाद
tj walker

सबसे अच्छे उदाहरण काफी स्पष्ट रूप से प्रलेखन से आते हैं। डेवलपर.
कीथ एडलर

6

एक अच्छी जानकारी: आपको यह जांचने की ज़रूरत नहीं है कि बंडल ऑब्जेक्ट onCreate () विधि में शून्य है या नहीं। OnRestoreInstanceState () पद्धति का उपयोग करें, जिसे सिस्टम onStart () विधि के बाद कॉल करता है। सिस्टम onRestoreInstanceState () को कॉल करता है केवल तभी जब कोई सहेजने के लिए सहेजा गया राज्य है, इसलिए आपको यह जांचने की आवश्यकता नहीं है कि बंडल रिक्त है या नहीं


5

जानकारी जमा करो:

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 में जानकारी को पुनर्स्थापित नहीं करना चाहते हैं:

यहाँ उदाहरण हैं: एक गतिविधि को फिर से बनाना

OnCreate () के दौरान राज्य को पुनर्स्थापित करने के बजाय आप onRestoreInstanceState () को लागू करना चुन सकते हैं, जिसे सिस्टम ऑनस्टार्ट () विधि के बाद कॉल करता है। सिस्टम onRestoreInstanceState () को कॉल करता है केवल तभी जब कोई सहेजने के लिए सहेजा गया राज्य है, इसलिए आपको यह जांचने की आवश्यकता नहीं है कि बंडल रिक्त है या नहीं

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

मूल रूप से onSaveInstanceState (बंडल आउटबंडल) आपको एक बंडल देगा। जब आप बंडल क्लास को देखते हैं, तो आप देखेंगे कि आप इसके अंदर बहुत सारे अलग-अलग सामान रख सकते हैं। OnCreate () के अगले कॉल पर, आपको बस उस बंडल को एक तर्क के रूप में वापस मिलता है। तब आप अपने मूल्यों को फिर से पढ़ सकते हैं और अपनी गतिविधि को बहाल कर सकते हैं।

कहते हैं कि आप एक EditText के साथ एक गतिविधि है। उपयोगकर्ता ने इसके अंदर कुछ पाठ लिखा था। उसके बाद सिस्टम आपके onSaveInstanceState () को कॉल करता है। आप EditText से पाठ को पढ़ते हैं और इसे बंडल में बंडल के माध्यम से लिखते हैं ।putString ("edit_text_value", theValue)।

अब onCreate कहा जाता है। आप जांच लें कि आपूर्ति की गई बंडल अशक्त तो नहीं है। यदि ऐसा होता है, तो आप अपना मान बंडल.getString ("edit_text_value") के माध्यम से पुनर्स्थापित कर सकते हैं और इसे अपने EditText में वापस रख सकते हैं।


0

यह अतिरिक्त जानकारी के लिए है।

इस परिदृश्य की कल्पना करें

  1. एक्टिवा लॉन्च एक्टीबी।
  2. एक्टिविटीबी ने एक नया एक्टिविटीप्रेम लॉन्च किया

    Intent intent = new Intent(getApplicationContext(), ActivityA.class);
    startActivity(intent);
  3. एक्टिविटी के साथ एक्टिविटी का कोई संबंध नहीं है।
    इस मामले में बंडल इन एक्टिविटीप्रेम.ऑनक्रिट () शून्य होगा।

यदि विभिन्न गतिविधियों के बजाय एक्टिवा और एक्टिविटीप्रेम एक ही गतिविधि होनी चाहिए, तो एक्टिविटीबी को स्टार्टएक्टिविटी () का उपयोग करने की तुलना में कॉल () खत्म होना चाहिए।


बस स्पष्ट करने के लिए, आपके उदाहरण में, एक्टिवा == एक्टिवा इंस्टेंस 1 और एक्टिविटीप्रेम == एक्टिवा उदाहरण 2 है? इसके अलावा, जब आप कहते हैं, "एक्टिविटीबी को स्टार्ट एक्टिविटी () का उपयोग करने की तुलना में खत्म () कॉल करना चाहिए।" क्या आपका मतलब है: (1) एक्टिविटीबी को फिनिश () कॉल करना चाहिए और फिर स्टार्ट एक्टिविटी () को बाद में (2) या एक्टिविटी को स्टार्ट (एक्टिविटी) का इस्तेमाल करने के बजाय फिनिश () को कॉल करना चाहिए? यदि आपके पास विकल्प 2 है, तो आप कैसे सुझाएंगे कि कोई व्यक्ति उसी गतिविधि को फिर से शुरू कर सकता है उदाहरण 1 इसलिए आप नष्ट होने / समाप्त होने से पहले निहित गतिविधि को डेटा लोड कर सकते हैं? धन्यवाद
cjayem13

एक्टिवा और एक्टिविटीप्रेम एक ही क्लास के हैं लेकिन अलग-अलग उदाहरण हैं। इस परिदृश्य में, एक्टिवा अभी तक अपने व्यवसाय को समाप्त नहीं कर रहा है, इसके बीच में, इसने एक्टीबी बनाया और शुरू किया, इसलिए एक्टिविटीबी खत्म होने पर, एक्टिवा को अपना शेष व्यवसाय जारी रखना चाहिए। इस मामले में startActivity को कॉल करना गलत है, और एक्टिवा और एक्टिविएप्राइम की उम्मीद करना एक ही उदाहरण है। इसलिए हमें एक्टिवा को फिर से शुरू नहीं करना चाहिए, एक्टिविटीबी को खत्म करना चाहिए और एक्टिवा को अपना ऑपरेशन फिर से शुरू करने देना चाहिए ...
ken

0

यदि डेटा savedInstanceStateकोड के उपयोग से लोड नहीं है ।
समस्या यह है कि url कॉल पूरी तरह से पूरी नहीं होती है, यदि जाँच की जाती है कि डेटा लोड है तो InstState मान दिखाने के लिए।

//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
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.