2013-02-13 30 views
8

मेरे आवेदन में FLAG_ACTIVITY_SINGLE_TOP और FLAG_ACTIVITY_CLEAR_TOP झंडे का उपयोग करके एक गतिविधि शुरू हुई है क्योंकि मैं यह सुनिश्चित करना चाहता हूं कि उस गतिविधि का केवल एक उदाहरण है ढेर के शीर्ष और पुराने उदाहरण के शीर्ष पर सभी गतिविधियां बंद हैं। अब तक सब ठीक है।स्पष्ट शीर्ष और एकल शीर्ष झंडे की आपूर्ति की जाने पर गतिविधि को मारने के बाद सही ढंग से बहाल नहीं किया गया है

अगला मैं परीक्षण करना चाहता था कि गतिविधि एक से अधिक बार बनाए जाने के बाद सही ढंग से पुनर्स्थापित हो जाती है और लगातार नष्ट हो जाती है। मैं Activity.setIntent() का उपयोग करके मैन्युअल रूप से इरादे को सेट करने का ख्याल रखता हूं, जब Activity.onNewIntent() कहा जाता है ताकि सबसे हालिया इरादा Activity.getIntent() द्वारा वापस किया जा सके। परीक्षण करने के लिए कि मैंने डेवलपर विकल्पों में "गतिविधियां न रखें" विकल्प को सक्रिय किया है, लेकिन गतिविधि को फिर से बनाया जाने पर Activity.getIntent() द्वारा वापस आ गया है, यह पहला इरादा है जिसने इसे बनाया है और हाल ही में नहीं।

यह जेबी और आईसीएस पर होता है, मैंने पुराने संस्करणों पर इसका परीक्षण नहीं किया है। क्या मैं कुछ गलत कर रहा हूं या क्या मैंने दस्तावेज़ों में कुछ गलत समझा?

उत्तर

16

यदि आप अपने ऐप को अग्रभूमि में रखते हुए मार देते हैं, तो यह वही नहीं है जब एंड्रॉइड आपके ऐप को मारता है (जो केवल तब होगा जब आपका ऐप पृष्ठभूमि में होगा)। यदि आप ऐप को मारते हैं और फिर ऐप को पुनरारंभ करते हैं, तो यह इसे फिर से शुरू करने जैसा है। यहां कोई "बहाल" नहीं चल रहा है। यदि आप onCreate() पर लॉगिंग जोड़ते हैं तो आपको यह देखना चाहिए कि आपके ऐप को मारने और पुनरारंभ करने के बाद, जो onCreate() पर पास हो गया है, शून्य है।

दुर्भाग्यवश यह समझना बहुत मुश्किल है कि एंड्रॉइड आपके ऐप को मारने पर क्या होता है।

संपादित करें: ओपी की टिप्पणी के बाद अधिक सामान जोड़ा

यहाँ चर्चा प्रयोजनों के लिए एक ठोस उदाहरण है।सबसे पहले डेवलपर विकल्प "गतिविधियों को न रखें" बिना:

  • ActivityA जड़ गतिविधि है
  • हम ActivityA
  • ActivityA.onCreate() शुरू कहा जाता है
  • ActivityA अब शुरू होता है ActivityB
  • ActivityB.onCreate() है कहा जाता है (गतिविधि स्टैक में अब ActivityA ->ActivityB)
  • ActivityB शुरू होता है FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP साथ ActivityA और एक अतिरिक्त "foo"
  • ActivityA.onNewIntent()Intent युक्त FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP और एक अतिरिक्त "foo"
  • ActivityB.onDestroy() कहा जाता है के बाद से गतिविधि ढेर ActivityA
वापस करने के लिए मुक्त कर दिया गया साथ कहा जाता हो जाता है

अब, वही काम करते हैं लेकिन डेवलपर विकल्प "गतिविधियों को न रखें" सक्षम करें (मैंने बोल्ड में पिछली परिदृश्य से अलग सामग्री को हाइलाइट किया है) :

  • ActivityA जड़ गतिविधि है
  • हम शुरू ActivityA
  • ActivityA.onCreate() कहा जाता है
  • ActivityA अब शुरू होता है ActivityB
  • ActivityB.onCreate() कहा जाता है (गतिविधि ढेर अब शामिल ActivityA ->ActivityB)
  • क्योंकि ActivityA बंद कर दिया है, एंड्रॉयड यह नष्ट कर देता है और कहता है ActivityA.onDestroy()
  • नोट: गतिविधि ढेर अभी भी ActivityA शामिल ->ActivityB है, भले ही इस समय ActivityA का कोई उदाहरण नहीं है। एंड्रॉयड सभी राज्य
  • ActivityB शुरू होता है FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP साथ ActivityA और एक अतिरिक्त "foo"
  • के बाद से एंड्रॉयड ActivityA का कोई उदाहरण पुन: सक्रिय करने है, यह एक बनाने के लिए की जरूरत है याद करते हैं, तो यह करता है और फिर ...
  • ActivityA.onCreate() ही Intent है कि यह जब ActivityA के मूल उदाहरण बनाया गया था के साथ बुलाया गया था के साथ कहा जाता है (यानी: कोई भी निशानी है और कोई अतिरिक्त के साथ लॉन्च प्रयोजन)
  • ActivityA.onNewIntent()Intent युक्त FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP के साथ बुलाया जाता है और एक अतिरिक्त "foo"
  • ActivityB.onDestroy() कहा जाता है के बाद से गतिविधि ढेर ActivityA

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

जब आप setIntent() पर कॉल करते हैं तो यह वास्तव में Intent को नहीं बदलता है जो एंड्रॉइड बचाता है और पुनर्स्थापित करता है। यह केवल इन-मेमोरी Intent को बदलता है जिसे कॉल से getIntent() पर वापस कर दिया जाएगा।

मुझे उम्मीद है कि यह अब स्पष्ट है। यदि नहीं, तो कृपया मुझे बताएं।

+0

मैंने वर्णन नहीं किया कि गतिविधि सही ढंग से कैसे मार दी जाती है। मैंने अभी अपना प्रश्न संपादित किया है। – futtetennista

+0

मैंने अधिक जानकारी में व्याख्या करने के लिए अपना उत्तर संपादित किया। –

+1

मुझे आपका आखिरी कथन मिल गया - जो बिल्कुल सही है, एंड्रॉइड करता है - थोड़ा उलझन में। ढांचे को पहले इरादे को क्यों बचाया जाना चाहिए, आखिरी नहीं? उन झंडे को जोड़कर मेरा इरादा आमतौर पर गतिविधि ए को कुछ अलग सामग्री दिखाने देता है। लेकिन अगर यह मारे गए और फिर पहले इरादे का उपयोग करके बहाल किया गया तो मैं पुरानी सामग्री को देख कर समाप्त कर दूंगा। आपने जो लिखा है उसमें एक संशोधन: आपके ऐप को मारने और पुनरारंभ करने के बाद, 'ऑनक्रेट() 'पर सहेजा गया बंडल शून्य पर नहीं है यदि आपने' सहेजे गए इंस्टेंसस्टेट() 'पर कुछ सहेजा है। – futtetennista

2

यह सुनिश्चित नहीं है कि आपको इसका समाधान मिला है या नहीं, लेकिन लक्ष्य गतिविधि & कॉल करने के लिए ऑनइन्टेंट (इरादा theNewIntent) विधि को ओवरराइड करना INTent (theNewIntent) ने इसे मेरे लिए हल किया है।

@Override 
protected void onNewIntent(Intent intent) { 
    super.onNewIntent(intent); 

    /* 
    * This overrides the original intent. 
    */  
    setIntent(intent); 
}