एक्टिविटी.फिनिश () विधि वास्तव में क्या कर रही है?


156

मैं थोड़ी देर के लिए एंड्रॉइड एप्लिकेशन विकसित कर रहा हूं, और गतिविधि जीवन चक्र, और एप्लिकेशन के जीवन चक्र के बारे में बहुत सारी पोस्ट का पालन कर रहा हूं।

मुझे पता है कि Activity.finish()विधि कहीं से भी कॉल करती है Activity.onDestroy(), और गतिविधि को स्टैक से हटाती है, और मुझे लगता है कि यह किसी भी तरह ऑपरेटिंग सिस्टम और कचरा संग्रहकर्ता को इंगित करता है कि वह "अपनी चाल चल सकता है" और मेमोरी को मुक्त कर सकता है जब यह एक अच्छा समय लगता है इसलिए....

मैं इस पोस्ट पर आया - क्या किसी आवेदन को छोड़ने पर रोक लगा दी गई है? और मार्क मर्फी का जवाब पढ़ें।

इसने मुझे थोड़ा भ्रमित कर दिया कि वास्तव में finish()विधि वास्तव में क्या करती है।

क्या कोई मौका है जिसे मैं फोन करूंगा finish()और onDestroy()बुलाया नहीं जाएगा?


जवाबों:


171

finish()किसी गतिविधि पर कॉल करते समय, विधि onDestroy()निष्पादित की जाती है। यह विधि निम्न कार्य कर सकती है:

  1. गतिविधि को प्रबंधित करने वाले किसी भी संवाद को खारिज करें।
  2. गतिविधि को प्रबंधित करने वाले किसी भी कर्सर को बंद करें।
  3. किसी भी खुले खोज संवाद को बंद करें

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


5
इतना खत्म () विधि केवल onDestroy () के लिए कॉल ट्रिगर है और यह बात है?
ताल कनाल

9
हां, यदि आप गतिविधि पर वापस आते हैं तोक्रीट () कहा जाएगा।
लुइस पैना

9
खत्म () भी onPause () और onStop () कहते हैं?
sr09

36
मैंने फिर से परीक्षण किया, और पाया कि onPause (), onStop () और onDestroy () सभी को कॉल खत्म होने के बाद क्रम में बुलाया जाएगा ()।
सैम ००३

5
@ लॉरेंट ऑनपॉज़ () और ऑनटॉप () को हमेशा नहीं कहा जाता है। नीचे दिए गए उत्तर में मेरा अवलोकन देखें
प्रकाश

77

@K_Anas के उत्तर पर मेरे 2 सेंट। मैंने फिनिश () पद्धति पर एक सरल परीक्षण किया। गतिविधि जीवन चक्र में महत्वपूर्ण कॉलबैक विधियों को सूचीबद्ध किया

  1. कॉलिंग खत्म () onCreate (): onCreate () -> onDestroy ()
  2. कॉलिंग फिनिश () ऑनस्टार्ट (): ऑनक्रिएट () -> ऑनस्टार्ट () -> ओनटॉप () -> ऑनस्टीरॉय ()
  3. कॉलिंग खत्म () onResume (): onCreate () -> onStart () -> onResume () -> onPause () -> onStop () -> onDestroy ()

मेरे कहने का मतलब यह है कि किसी भी तरीके के बीच के तरीकों के समकक्षों को समाप्त होने पर () निष्पादित किया जाता है।

उदाहरण के लिए:

 onCreate() counter part is onDestroy()
 onStart() counter part is onStop()
 onPause() counter part is onResume()

क्या होगा अगर आप ऑनपॉज के अंदर खत्म कहते हैं? इसे onStop> onDestroy कहेंगे?
21

यही कारण है कि तालिका वास्तव में उपयोगी और वर्णनात्मक (आप एक छोटा सा नीचे स्क्रॉल करना) है developer.android.com/reference/android/app/...
winklerrr

मैंने स्वयं सत्यापित किया है कि यह उत्तर सही है।
श्रीकांत करुमनघाट

33

यह भी देखें कि क्या आप एक इरादे के बाद कॉल खत्म करते हैं ("बैक" बटन के साथ पिछली गतिविधि पर वापस नहीं जा सकते

startActivity(intent);
finish();

यह ठीक वही जानकारी है जिसकी मुझे ज़रूरत थी, क्योंकि मेरे पास एक गतिविधि है जो केवल Google ड्राइव से जुड़ती है, फिर यह अपनी जाँच करता है और यह मुख्य गतिविधि (या यदि कोई त्रुटि होती है तो सेटिंग्स गतिविधि पर जाती है), तो उपयोगकर्ता को चाहिए 'वापस जाने में सक्षम नहीं है।
फ्रांसेस्को मार्केटी-स्टैसी

1
@Francesco Marchetti-Stasi आपके मामले में यह onBackPressed () को ओवरराइड करना बेहतर होगा और यदि उपयोगकर्ता वापस नहीं जाना चाहिए, तो इसमें super.onBackPressed () कॉल न करें।
पॉल

13

onDestroy()अंतिम सफाई के लिए है - खुले कनेक्शन, पाठकों, लेखकों आदि को बंद करने वाले संसाधनों को मुक्त करना। यदि आप इसे ओवरराइड नहीं करते हैं, तो सिस्टम वही करता है जो उसके पास है।

दूसरी ओर, finish()सिस्टम को यह पता करने देता है कि प्रोग्रामर चाहता है कि करंट Activityसमाप्त हो जाए। और इसलिए, यह कॉल करता हैonDestroy() उसके बाद है।

नोट करने के लिए कुछ:

यह आवश्यक नहीं है कि केवल एक कॉल finish()ट्रिगर को कॉल करे onDestroy()। नहीं, जैसा कि हम जानते हैं, एंड्रॉइड सिस्टम गतिविधियों को मारने के लिए स्वतंत्र है यदि यह महसूस करता है कि वर्तमान द्वारा आवश्यक संसाधन Activityहैं जिन्हें मुक्त करने की आवश्यकता है।


1
आपने लिखा है कि खत्म () सिस्टम को बताएं कि गतिविधि को समाप्त करने की आवश्यकता है। इसलिए यह कहना पसंद है कि "x x = सिस्टम को x करने के लिए कहें"। सेकंड की बात: आपके जवाब से ऐसा लगता है कि एक ऐसा तरीका है जिसे मैं खत्म () कहूंगा, और सिस्टम तय करेगा कि onDestroy () नहीं कहेंगे? क्या यह संभव है?
ताल कनाल

आपको पहला भाग सही मिला। कॉलिंग finish()सिस्टम को खत्म करने के लिए कह रहा है Activity। आपके कथन में "x" भाग "समाप्त (नष्ट) Activity" करने के लिए है। दूसरा हिस्सा गलत है। दरअसल, मुझे वहां एक शब्द याद आ गया। मैंने उत्तर संपादित किया है। onDestroy()इसके द्वारा ट्रिगर नहीं किया जाता है finish(), सिस्टम इसे स्वयं भी कह सकता है।
काजेकेज गारा

1
मैंने उत्तर के लिए सिर्फ आपका जोड़ पढ़ा है। अभी तक मैंने आपके स्पष्टीकरण को उत्तर देने के कारण का जवाब दिया है, लेकिन मैं यह देखना चाहूंगा कि क्या अन्य लोगों के पास "उत्तर" के रूप में चिह्नित करने से पहले इसके बारे में कुछ और कहना होगा। अभी के लिए धन्यवाद :)
ताल कनाल

तो खत्म होने के बाद (), इस गतिविधि के सभी चर नष्ट हो जाएंगे, है ना? जब मैं एक बार फिर से इस गतिविधि में वापस आऊंगा, तो उन्हें फिर से घोषित या आरंभ किया जाएगा, है ना?
Sibbs जुआ

3
नोट: यदि सिस्टम प्रक्रिया को मारता है, तो onDestroy को नहीं कहा जा सकता है। डेवलपर
केविन ली

9

समाप्त () विधि वर्तमान गतिविधि को नष्ट कर देगी। आप इस विधि का उपयोग उन मामलों में कर सकते हैं जब आप यह गतिविधि बार-बार लोड नहीं करना चाहते हैं जब उपयोगकर्ता बैक बटन दबाता है। मूल रूप से यह .Current स्टैक से गतिविधि को साफ़ करता है।


8

ऊपर @rommex उत्तर के अलावा, मैंने यह भी देखा है कि finish()गतिविधि के विनाश को कतारबद्ध करता है और यह गतिविधि प्राथमिकता पर निर्भर करता है।

अगर मैं फोन finish()के बाद onPause(), मैं देख रहा हूँ onStop(), और onDestroy()तुरंत बुलाया।

अगर मैं फोन finish()के बाद onStop(), मैं नहीं दिख रहा है onDestroy()5 मिनट बाद जब तक।

मेरे अवलोकन से, ऐसा लगता है कि फिनिश पंक्तिबद्ध है और जब मैंने देखा कि adb shell dumpsys activity activitiesइसे सेट किया गया था finishing=true, लेकिन चूंकि यह अब अग्रभूमि में नहीं है, इसलिए इसे विनाश के लिए प्राथमिकता नहीं दी गई थी।

सारांश में, onDestroy()कभी भी बुलाए जाने की गारंटी नहीं है, लेकिन यहां तक ​​कि जिस मामले में यह कहा जाता है, उसमें देरी हो सकती है।


5

विभिन्न उत्तर और नोट यह दावा कर रहे हैं कि फिनिश () ऑनपॉज़ () और ऑनस्पॉट () को छोड़ सकता है और सीधे ऑनडेस्ट्रॉय () को निष्पादित कर सकता है। निष्पक्ष होने के लिए, इस पर Android प्रलेखन ( http://developer.android.com/reference/android/app/Activity.html ) नोट्स "गतिविधि सिस्टम द्वारा खत्म या नष्ट हो रही है" जो बहुत अस्पष्ट है, लेकिन सुझाव दे सकता है कि खत्म () onDestroy () में कूद सकता है।

JavaDoc on फिनिश () समान रूप से निराशाजनक है ( http://developer.android.com/reference/android/app/Activity.html#finish () ) और वास्तव में नोट नहीं करता है कि क्या विधि (ओं) को समाप्त होने के जवाब में कहा जाता है ()।

इसलिए मैंने नीचे इस मिनी-ऐप को लिखा है जो प्रविष्टि पर प्रत्येक राज्य को लॉग करता है। इसमें एक बटन शामिल है जो कॉल को समाप्त करता है () - ताकि आप लॉग देख सकें कि किन तरीकों से निकाल दिया जाता है। इस प्रयोग ने सुझाव दिया कि फिनिश () वास्तव में ऑनपॉज़ () और ऑनस्पॉट () को कॉल करता है । यहाँ उत्पादन मुझे मिल रहा है:

2170-2170/? D/LIFECYCLE_DEMO INSIDE: onCreate
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onStart
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onResume
2170-2170/? D/LIFECYCLE_DEMO User just clicked button to initiate finish() 
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onPause
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onStop 
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onDestroy

package com.mvvg.apps.lifecycle;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class AndroidLifecycle extends Activity {

    private static final String TAG = "LIFECYCLE_DEMO";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "INSIDE: onCreate");
        setContentView(R.layout.activity_main);
        LinearLayout layout = (LinearLayout) findViewById(R.id.myId);
        Button button = new Button(this);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                Toast.makeText(AndroidLifecycle.this, "Initiating finish()",
                        Toast.LENGTH_SHORT).show();
                Log.d(TAG, "User just clicked button to initiate finish()");
                finish();
            }

        });

        layout.addView(button);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "INSIDE: onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "INSIDE: onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "INSIDE: onDestroy");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "INSIDE: onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "INSIDE: onResume");
    }

}

3

@ user3282164 गतिविधि जीवन-चक्र के अनुसार कॉल करने पर onPause()-> onStop()- -> से गुजरना चाहिएonDestroy()finish()

आरेख onDestroy()प्रणाली के कारण [गतिविधि चल] से [ ] तक कोई सीधा रास्ता नहीं दिखाता है।

onStop () डॉक्टर का कहना है " ध्यान दें कि यह विधि हो सकती है कभी भी नहीं बुलाया जा सकता है, कम स्मृति स्थितियों में जहां सिस्टम में पर्याप्त मेमोरी नहीं होती है ताकि वह ऑनपॉज () विधि के बाद आपकी गतिविधि की प्रक्रिया को चालू रख सके। "


बिल्कुल नहीं देखें: stackoverflow.com/questions/12655898/…
ceph3us

2

मेरे अध्ययन से पता चलता है कि finish() विधि वास्तव में कतार में कुछ विनाश कार्यों को रखती है, लेकिन गतिविधि तुरंत नष्ट नहीं होती है। विनाश हालांकि निर्धारित है।

उदाहरण के लिए, यदि आप कॉलबैक finish()में जगह onActivityResult()लेते हैं, जबकि onResume()अभी तक चलना है, तो पहले onResume()निष्पादित किया जाएगा, और उसके बाद ही onStop()औरonDestroy() कहा जाता है।

नोट: दस्तावेज़onDestroy() पर कहा गया है, बिल्कुल नहीं बुलाया जा सकता है ।


2

onCreate () में कॉलिंग खत्म नहीं होगी onDestroy () सीधे @prakash ने कहा। finish()आपरेशन भी शुरू नहीं होगी जब तक आप Android के लिए नियंत्रण वापस जाएँ।

OnCreate में कॉलिंग फिनिश () : onCreate () -> onStart () -> onResume () । यदि उपयोगकर्ता ऐप से बाहर निकलता है -> onPause () -> onStop () -> onDestroy ()

कॉलिंग फिनिश () ऑनस्टार्ट () : ऑनक्रिएट () -> ऑनस्टार्ट () -> ओनटॉप () -> ऑनस्टीरॉय ()

कॉलिंग खत्म () onResume () : onCreate () -> onStart () -> onResume () -> onPause () -> onStop () -> onDestroy ()

आगे के संदर्भ के लिए इस ऑन्क्रीट को देख लें कि फिनिश के बाद निरंतर और खत्म होने के बाद ()


0

ऐसा लगता है कि यहाँ अभी तक एकमात्र सही उत्तर रोमनेक्स द्वारा दिया गया है: "ऑनडेस्ट्रो () को बिल्कुल भी नहीं बुलाया जा सकता है"। व्यवहार में भले ही, लगभग सभी मामलों में, इसकी कोई गारंटी नहीं है: प्रलेखन खत्म () केवल वादा करता है कि गतिविधि का परिणाम कॉलर को वापस प्रचारित किया जाता है, लेकिन इससे अधिक कुछ नहीं। इसके अलावा, जीवनचक्र दस्तावेज में स्पष्ट किया गया है कि ओएस द्वारा गतिविधि को मार डाला जा सकता है जैसे ही ऑनटॉप () पहले (या पुराने उपकरणों पर भी) खत्म हो जाता है, जो कि एक साधारण परीक्षण में निरीक्षण करने के लिए संभावना नहीं है और इसलिए दुर्लभ है, इसका मतलब यह हो सकता है कि गतिविधि onDestroy () निष्पादित होने से पहले या उससे पहले भी मारा जा सकता है।

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


-4

खत्म () बस Android में पिछली गतिविधि को वापस भेजता है, या आप कह सकते हैं कि यह आवेदन में एक कदम पीछे जा रहा है

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