2013-04-10 5 views
18

मैं onSaveInstanceStateFragment रों के लिए बुलाया जा रहा है नहीं के बारे में कुछ इसी तरह के सवाल देखा है, लेकिन मेरे मामले Fragment काम ठीक में, यह मुख्य FragmentActivity कि परेशानी हो रही है।FragmentActivity onSaveInstanceState नहीं बुलाया हो रही

प्रासंगिक कोड काफी सरल लग रहा है:

public class MyFActivity extends FragmentActivity implements ActionBar.TabListener { 
    String[] allValues; // data to save 

    @Override 
    protected void onSaveInstanceState (Bundle outState) { 
     Log.d("putting it!", allValues.toString()); 
     outState.putStringArray("allValues", allValues); 
     super.onSaveInstanceState(outState); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (savedInstanceState != null) { 
      allValues = savedInstanceState.getStringArray("allValues"); 
      Log.d("getting it!", allValues.toString()); 
     } 
    } 
} 

जब गतिविधि (वापसी बटन का प्रयोग) को रोक कर, onSaveInstanceState कभी नहीं कहा जाता है, और फलस्वरूप, savedInstanceState हमेशा null एप्लिकेशन शुरू करने पर onCreate विधि के भीतर है । मैं इस तरह एक ब्लॉक को जोड़ने की कोशिश की:

@Override 
public void onPause() { 
    super.onPause(); 
    onSaveInstanceState(new Bundle());  
} 

जो https://stackoverflow.com/a/14195202/362657 में सुझाव दिया गया था, लेकिन जब onSaveInstanceState तो कहा जाता हो जाता है, savedInstanceStateonCreate विधि के भीतर null बनी हुई है। मैं क्या खो रहा हूँ?

+3

"गतिविधि को रोकते समय (बैक बटन का उपयोग करके)" आमतौर पर यह फ्रैगमेंट को नष्ट कर देता है, इसलिए 'savedInstanceState' खो जाता है। जब आप डिवाइस को घुमाते हैं तो क्या आपको 'onCreate()' में उपयुक्त 'saveInstanceState' दिखाई देता है? – Sam

+0

ऑनक्रेट की बजाय, शायद आपको रेज़्यूम() पर उपयोग करना चाहिए? यदि गतिविधि केवल रोका गया है, तो ऑनक्रेट() को दोबारा नहीं बुलाया जाना चाहिए, रेज़्यूम() – Tom

+0

एचएम होना चाहिए, जो इसे समझाता है! इसे नष्ट कर दिया गया है। – SaltyNuts

उत्तर

77

यहां मुद्दा यह है कि आप गलतफहमी कर रहे हैं कि onSaveInstanceState काम करता है। यह Activity/Fragment की स्थिति को सहेजने के लिए डिज़ाइन किया गया है ताकि ओएस को स्मृति कारणों या कॉन्फ़िगरेशन परिवर्तनों के लिए इसे नष्ट करने की आवश्यकता हो। Activity/Fragment को वापस/पुनरारंभ करने पर यह स्थिति onCreate में वापस पारित की जाती है।

Fragment में, उनके सभी जीवन चक्र कॉलबैक सीधे उनके माता-पिता Activity से बंधे हैं। तो onSaveInstanceState को Fragment पर कॉल किया जाता है जब उसके माता-पिता Activity में onSaveInstanceState कहा जाता है।

जब गतिविधि (वापसी बटन का प्रयोग) को रोक कर, onSaveInstanceState कहा जाता है कभी नहीं है, और फलस्वरूप, savedInstanceState हमेशा एप्लिकेशन शुरू करने पर onCreate विधि के भीतर रिक्त है।

जब वापस दबाने, उपयोगकर्ता Activity को नष्ट कर रहा है, और इसलिए अपने बच्चों Fragment रों है, इसलिए, onSaveInstanceState कॉल करने के लिए के बाद से उदाहरण नष्ट किया जा रहा है कोई कारण नहीं है। जब आप Activity को दोबारा खोलते हैं, तो यह कोई नया नया उदाहरण नहीं है, बिना सहेजे गए राज्य के, BundleonCreate में null में पारित किया गया है। यह बिल्कुल डिजाइन के रूप में व्यवहार कर रहा है। हालांकि, डिवाइस को घूर्णन करने या होम बटन पर क्लिक करने का प्रयास करें, तो आप Activity देखेंगे और इसके बच्चे Fragment के पास onSaveInstanceState कहा जाता है, और वापस लौटने पर onCreate में वापस भेज दिया जाता है।

हैक आप कहा, सीधे कॉल onSaveInstanceState(new Bundle()); के अंदर, एक बहुत ही बुरा व्यवहार है जैसा कि आप चाहिए कभी नहीं कॉल जीवन चक्र कॉलबैक सीधे। ऐसा करने से आपका ऐप अवैध राज्यों में डाल सकता है।

यदि आप वास्तव में चाहते हैं कि आपके डेटा के लिए आपके ऐप के उदाहरण से परे बने रहें, तो मेरा सुझाव है कि आप अधिक उन्नत डेटा के लिए SharedPreferences या databases का उपयोग करने के लिए देखें। फिर आप onPause() या जब भी यह बदलते हैं, तो अपने लगातार डेटा को सहेज सकते हैं।

उम्मीद है कि इससे मदद मिलती है।

+0

पूरी तरह से स्पष्टीकरण के लिए धन्यवाद। मैं गलत धारणा के तहत था कि बैक बटन पृष्ठभूमि में गतिविधि को रोकता है, इसे नष्ट नहीं करता है। – SaltyNuts

+0

आपका स्वागत है, यह एक मुश्किल अवधारणा है, और दस्तावेज नहीं है साथ ही मैं देखना चाहता हूं। –

+0

@dymmeh यह कमाल है, आपको सर –

7

स्वीकार किए जाते हैं जवाब के लिए एक अद्यतन में:

यदि आप एक FragmentStatePagerAdapter (बल्कि FragmentPagerAdapter से)

FragmentStatePagerAdapter

इस के साथ एक ViewPager उपयोग कर रहे हैं एक टुकड़ा के onSaveInstanceState कहा जा सकता है पेजर की संस्करण अधिक उपयोगी होती है जब बड़ी संख्या में पेज होते हैं, एक सूची दृश्य की तरह काम करते हैं। जब उपयोगकर्ता उपयोगकर्ता के लिए दृश्यमान नहीं होते हैं, तो उनका पूरा टुकड़ा नष्ट हो सकता है, केवल उस खंड की सहेजी गई स्थिति को ही रखा जा सकता है। पेजर के बीच स्विच करते समय संभावित रूप से अधिक ओवरहेड की लागत पर FragmentPagerAdapter की तुलना में पेजर प्रत्येक विज़िट किए गए पृष्ठ से जुड़े बहुत कम स्मृति को पकड़ने की अनुमति देता है।

और भूल नहीं है:

जब मेजबान ViewPager FragmentPagerAdapter का उपयोग कर एक वैध पहचान पत्र सेट होना चाहिए।

+0

आपने अपना जीवन बचाया: डी –

संबंधित मुद्दे