पुरानी गतिविधि समाप्त करें और एक नया शुरू करें या इसके विपरीत


80

मुझे पता है, कि मुझे दोनों कोड स्निपेट के समान परिणाम मिलते हैं

finish();
startActivity(newActivity);

तथा

startActivity(newActivity);
finish();

मैं आपकी राय जानना चाहता हूं, अगर उनके बीच कोई बड़ा अंतर है। क्या यह दूसरे से बढ़िया है? यदि हां, तो क्यों?

जवाबों:


61

जब आप startActivity () करते हैं, तो वह सब घटनाओं की एक कतार में आपके इरादे को पोस्ट करता है। गतिविधि की वास्तविक शुरुआत निकट भविष्य में अतुल्यकालिक रूप से होती है। इसलिए मुझे दोनों में बड़ा अंतर नहीं दिखता।


1
यह मेरे लिए समझदारी से अच्छा लगता है
Tima

6
मेरे लिए एनीमेशन अलग है। नीचे मेरा जवाब देखें।
मॉन्स्टिएर

लेकिन दृष्टिकोण पूरी तरह गलत है .. झंडे हैं (इरादे के साथ-साथ प्रकट में) जो वास्तव में इस उपयोग के मामलों के लिए मौजूद हैं।
इवोकस

@ ईवोक हेड जाओ, क्या मतलब है, कौन से झंडे?
एंथनी

3
ऐप टास्क व्यवहार में वास्तव में एक बड़ा अंतर है। मैंने एक अलग उत्तर में मामले को विस्तृत किया।
विट खूदेंको

27

एनीमेशन स्पष्ट रूप से अलग है (कम से कम 4.1 बाद में)। कॉलिंग finish()पहले से पहले की गतिविधि को फीका करना शुरू कर देती है और नई गतिविधि में आने से पहले आप एक काले रंग की पृष्ठभूमि देख सकते हैं। startActivity()पहले कॉलिंग में नई गतिविधि पुराने के शीर्ष पर फीकी पड़ जाती है और काली पृष्ठभूमि दिखाई नहीं देती है।


16

के आदेश के आधार पर आवेदन कार्य व्यवहार में एक महत्वपूर्ण अंतर है startActivity()औरfinish() चालान ।

मैं जिस केस का वर्णन कर रहा हूं, वह केवल उस स्थिति में होता है जब वर्तमान गतिविधि (एक को रोका जाना) कार्य में एकमात्र है।

आम तौर पर आप उम्मीद करेंगे कि आरंभिक आशय (आप किसी अन्य गतिविधि को शुरू करने के लिए बनाए गए इरादे) प्रणाली द्वारा परिवर्तित नहीं किया गया है। और अगर अंतिमfinish() पर कॉल किया जाए तो ऐसा नहीं है कॉल करने से पहले कार्य में गतिविधिstartActivity()

इस मामले में एक्टिविटी मैनजर, ​​एक सिस्टम कंपोनेंट, जो कि ऐड्स को निष्पादित करता startActivity() है Intent.FLAG_ACTIVITY_NEW_TASK ध्वज अपने इरादे के लिए।

जब ऐसा होता है, तो किसी को इस तरह से लॉगकैट में लॉग एंट्री की सूचना मिल सकती है:

डब्ल्यू / एक्टिविटी मैनजर: स्टार्टिंग एक्टिविटी जिसे फिनिशिंग एक्टिविटीकार्ड कहा जाता है {4a19b47 u0 com.foo.bar/com.foo.bar.plashActivity t4928 f}; जबरदस्ती Intent.FLAG_ACTIVITY_NEW_TASK के लिए: इरादा {cmp = com.foo.bar / com.foo.bar.MainActivity}

और यह वह मोड़ है जहां से (कुछ शर्तों के तहत) चीजें गलत हो सकती हैं।

योग करने के लिए, यदि आप एक सुरक्षित पक्ष पर होना चाहते हैं ( FLAG_ACTIVITY_NEW_TASKइरादे में जोड़े जा रहे अप्रत्याशित प्रभावों का अनुभव करने के बजाय ), तो आदेश होना चाहिए:

  • startActivity()
  • finish()

डेमो प्रोजेक्ट

स्क्रीन रिकॉर्डिंग:


स्रोत कोड को देखते हुए, Activity.startActivity () अंततः कॉल करता है ActivThread.sendActivityResult () जो बदले में शिड्यूल कॉल करता हैSendResult () जो सिर्फ एक कतार में गतिविधि जोड़ता है। एक थ्रेड इसे बाद में संसाधित करेगा। दूसरी ओर खत्म () कॉल करता है ActivManagerNative.finishActivity () जो गतिविधि को तुरंत समाप्त करता है।
इमैनुएल

@ इमानुएल, मैं यह पता लगाने में विफल हो रहा हूं कि आपका कथन मेरे द्वारा बताए गए मुद्दे से संबंधित है या नहीं। :)
विट खूदेंको

9

Emmanuels जवाब के अलावा:

दोनों ही तरीकों से startActivityऔर finishशेड्यूल कर दिया जाएगा के बाद के बाद से दोनों यूआई धागा द्वारा कार्रवाई की जाती है, प्रेरक विधि के अंत।


7

मैं दूसरी पसंद करूंगा, मैं आधिकारिक स्रोतों से जो कुछ भी देख रहा हूं, उस पर यह समर्थन नहीं कर रहा हूं, लेकिन, नई गतिविधि को लॉन्च करने से पहले आपको कॉल खत्म करने से अधिक समझ में आता है, इस तरह से नई गतिविधि एक इरादे से पॉप अप होती है , और अब पृष्ठभूमि गतिविधि अपने सभी सफाई तरीकों को कॉल कर सकती है।

यदि आप इसे दूसरे तरीके से कर रहे थे, तो शायद सफाई करने से पहले इरादे में आग लगने का समय न हो। गतिविधि समाप्त होने के बाद गतिविधि कॉल शुरू होगी () कॉल?

मुझे उम्मीद है कि आप समझ गए होंगे कि मैं क्या करने की कोशिश कर रहा हूं, मैं दूसरा विकल्प सिर्फ सुरक्षित रहने के लिए करूंगा।


हां, मैं आपके विचार को समझ गया। यह तर्कसंगत लगता है। लेकिन मैं कल्पना नहीं कर सकता, जब यह स्थिति संभव हो सकती है
Tima

2

मेरा भी यही मुद्दा था:

Activity A: singleInstance
Activity B: singleInstance
Activity C: singleInstance

A starts B 
B starts C
C wants to start A:

यहाँ अगर मैं उपयोग करता हूँ:

finish();
startActivity(A);

कुछ वायर्ड होता है: ए के बजाय गतिविधि बी अग्रभूमि में आती है! लेकिन अगर मैं इस तरह से कोड बदलूं:

startActivity(A);
finish();

सब कुछ ठीक लगता है और गतिविधि ए दिखाई देती है।

मुझे नहीं पता कि समस्या क्या है, लेकिन ऐसा लगता है कि पहली स्थिति में, स्टार्ट स्टार्ट कमांड को निष्पादित करने से पहले सी समाप्त हो जाता है ताकि बैक स्टैक स्थिति को संभाल ले और अपनी शीर्ष गतिविधि को दिखाए जो कि बी है! लेकिन दूसरे मामले में, सब कुछ सामान्य रूप से होता है।


जब आप एप्लिकेशन समाप्त करते हैं (), Android LRU गतिविधि को स्टैक से खींचता है, जो कि बी। है। इससे मुझे लगता है कि खत्म () तत्काल और अतुल्यकालिक नहीं है।
मेहेत AV MehAR

0

मैं आमतौर पर startActivity()पहले करता हूंfinish() सोचता हूं कि कि नई स्क्रीन बाहर निकलेगी, यह सुनिश्चित हो जाएगा।

मेरे ऐप में एक लॉगिन पेज है। उपयोगकर्ता लॉगिन सफलतापूर्वक होने के बाद, लॉगिन गतिविधि चली गई है और मुख्य गतिविधि चालू है। यह एंड्रॉइड 4 में ठीक काम करता है।

आज मैं इसे मटीरियल डिज़ाइन में फिर से लिखना चाहता था। हालांकि, मुझे एक बड़ी समस्या मिल गई। न्यू एंड्रॉइड स्टूडियो सामग्री डिजाइन के साथ रिक्त गतिविधि बनाता है जो मुझे लगता है कि कई संसाधन लेता है। वही प्रक्रिया, लेकिन मुझे त्रुटि मिली

11-26 18:20:44.450 18397-18397/? I/Choreographer: Skipped 42 frames!  The application may be doing too much work on its main thread.
11-26 18:20:44.485 18397-18408/? I/art: Background partial concurrent mark sweep GC freed 2864(191KB) AllocSpace objects, 4(43MB) LOS objects, 13% free, 100MB/116MB, paused 8.056ms total 39.767ms

इसने कहा कि मेरे mainActivityफोन लॉगकैट में शुरू होने पर मेरे ऐप कई संसाधन ले लेते हैं । मेरे पास कुछ नहीं हैmainActivity बस कि यह डिफ़ॉल्ट सामग्री डिज़ाइन लेआउट है।

मैंने आदेश को उलट दिया और अब यह मेरे फोन पर त्रुटि के बिना काम करता है।

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