2012-06-01 30 views
106

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

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

मैं इस पोस्ट पर आया - Is quitting an application frowned upon? और मार्क मर्फी के जवाब को पढ़ें।

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

क्या कोई मौका है कि मैं finish() और onDestroy() पर कॉल नहीं करूंगा?

उत्तर

119

जब finish() एक गतिविधि पर बुला, विधि onDestroy() निष्पादित किया जाता है इस विधि की तरह कर सकते हैं:

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

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

+4

तो खत्म करें() विधि केवल डेस्ट्रॉय() पर कॉल ट्रिगर करना और यह है? –

+0

हां यह डेस्ट्रॉय() पर ट्रिगर करता है जो गतिविधि की अवधारणा का सम्मान करने वाली गतिविधि को नष्ट कर देगा जीवन चक्र –

+0

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

12

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

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

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

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

+1

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

+0

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

+1

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

5

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

-5

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

में वापस
2

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

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

दस्तावेज़ कहते हैं "ध्यान दें कि यह विधि कभी नहीं कम स्मृति स्थितियों में, कहा जा सकता है जहां प्रणाली के लिए पर्याप्त स्मृति नहीं है अपनी गतिविधि की प्रक्रिया() विधि कहा जाता है इसकी onPause के बाद चालू रखने के लिए।"

+0

** बिल्कुल नहीं ** देखें: http://stackoverflow.com/questions/12655898/finish-and-the-activity-lifecycle/30227647#30227647 – ceph3us

3

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

फिनिश() पर जावाडॉक इसी तरह निराशाजनक (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"); 
    } 

} 
42

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

  1. में महत्वपूर्ण कॉलबैक तरीकों OnCreate (में खत्म() कॉलिंग): OnCreate() -> OnDestroy()
  2. कॉलिंग onStart() में खत्म(): OnCreate() -> onStart() -> onStop() -> OnDestroy()
  3. onResume() में खत्म() कॉलिंग: onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> ऑनडेस्ट्राय()

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

जैसे:

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

क्या होगा यदि आप अंदर के अंदर खत्म कॉल करते हैं? यह ऑनटॉप> ऑन डस्ट्रॉय पर कॉल करेगा? – rmpt

+0

वह तालिका वास्तव में उपयोगी और वर्णनात्मक है (आपको थोड़ा सा स्क्रॉल करना होगा) https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle – winklerrr

+0

@ विंकलर अच्छा है। हाँ यह उपयोगी है – Prakash

1

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

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

नोट: को बिल्कुल भी नहीं कहा जा सकता है, जैसा कि documentation पर बताया गया है।

0

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

तो यदि आप यह सुनिश्चित करना चाहते हैं कि जब आप फिनिश() को कॉल करते हैं तो कुछ काम किया जाता है, तो आप इसे डेस्ट्रॉय() पर नहीं डाल सकते हैं, लेकिन उसी जगह में ऐसा करने की आवश्यकता होगी जहां आप फिनिश() कहते हैं, वास्तव में ठीक पहले इसे बुलाओ

1

ऑनरेट() में कॉलिंग खत्म होने पर डेड्रॉय() को सीधे कॉल नहीं किया जाएगा क्योंकि @prakash ने कहा। finish() ऑपरेशन तब तक शुरू नहीं होगा जब तक आप एंड्रॉइड पर नियंत्रण वापस नहीं ले लेते। OnCreate (में

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

onStart में खत्म()() कॉलिंग: OnCreate() -> onStart() -> onStop() -> OnDestroy()

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

आगे संदर्भ के लिए इस oncreate continuous after finishपर देखेंabout finish()

3

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

startActivity(intent); 
finish();