2015-03-04 8 views
8

गतिविधि को छोड़ने के बाद अंतिमकर्ता को कभी भी बुलाया नहीं जाता है। क्या इसका मतलब यह है कि गतिविधि अभी भी जिंदा है, भले ही मैं अगली गतिविधि में चले जाऊं।Xamarin एंड्रॉइड फ़ाइनलाइज़र को किसी अन्य गतिविधि पर जाने के लिए गतिविधि छोड़ने पर कॉल नहीं किया जा रहा है

namespace XamarinTest { 
[Activity(Label = "XamarinTest", Icon = "@drawable/icon")] 
public class MainActivity : Activity { 
    private int count = 1; 

    private TextView density; 

    protected override void OnCreate(Bundle bundle) { 
     base.OnCreate(bundle); 
     // Set our view from the "main" layout resource 
     SetContentView(Resource.Layout.ScreenData); 
     density = FindViewById<TextView>(Resource.Id.Density); 

     var pendingInent = new Intent(); 
     pendingInent.SetFlags(ActivityFlags.ClearTop); 
     pendingInent.SetClass(this, typeof(TestActivity)); 
     StartActivity(pendingInent); 
     Finish(); 
    } 


    ~MainActivity() { 

     Console.WriteLine("Finalizer called"); 
    } 

    protected override void Dispose(bool disposing){ 
     if (disposing) { 
      density.Dispose(); 
      density = null; 
     } 
     base.Dispose(disposing); 
    } 

    } 
} 

उत्तर

26

यह वास्तव में उल्लेखनीय जटिल है; गतिविधि अभी भी जिंदा होने के बारे में संक्षिप्त जवाब है, हां और नहीं है। बशर्ते आपने अपने Activity के लिए संसाधनों को सही तरीके से साफ कर दिया है, तो आपकी गतिविधि को कचरा कलेक्टर द्वारा साफ़ किया जाएगा (अंततः)।

सफाई के संबंध में, यह आयात करने के लिए आयात किया गया है कि Xamarin discourages (slide 44 onwards) अंतिमकरण का उपयोग कर।

  • वे किसी भी समय सीमा के भीतर चलने की गारंटी नहीं कर रहे हैं: यहां इसका कारण बताया।
  • वे एक विशिष्ट अनुक्रम में नहीं चलते हैं।
  • वे ऑब्जेक्ट्स को लंबे समय तक जीते हैं।
  • जीसी अप्रबंधित संसाधनों के बारे में नहीं जानता है।

    protected override void OnDestroy() 
    { 
        base.OnDestroy(); 
        this.Dispose(); // Sever java binding. 
    } 
    
    :

इसलिए, एक finalizer का उपयोग कर सफाई प्रदर्शन करने के लिए काम करने के गलत तरीके से यह OnDestroy कॉलबैक है में है ... आप यह सुनिश्चित करें कि MainActivity नष्ट हो जाता है चाहते हैं, मैन्युअल रूप से Activity निपटान

इससे मोनो peer object कनेक्शन तोड़ने और अगले कचरा संग्रहण चक्र (GC.Collect(GC.MaxGeneration)) के दौरान गतिविधि को नष्ट कर देगा। दस्तावेज़ों से:

ऑब्जेक्ट जीवनकाल को छोटा करने के लिए, Java.Lang.Object.Dispose() को लागू किया जाना चाहिए। यह वैश्विक संदर्भ को मुक्त करके दो वीएम के बीच ऑब्जेक्ट पर कनेक्शन को मैन्युअल रूप से "अलग" कर देगा, इस प्रकार ऑब्जेक्ट्स को तेज़ी से एकत्रित करने की अनुमति मिल जाएगी।

नोट कॉल आदेश वहाँ, this.Dispose() किसी भी कोड है जो Android भूमि में वापस आह्वान के बाद बुलाया जाना चाहिए। क्यूं कर? जावा और .NET के बीच सभी कनेक्शन अब एंड्रॉइड को संसाधनों को पुनः प्राप्त करने की अनुमति देने के लिए टूटा हुआ है, इसलिए एंड्रॉइड-भूमि ऑब्जेक्ट्स (फ्रैगमेंट, एक्टिविटी, एडाप्टर) का उपयोग करने वाला कोई भी कोड असफल हो जाएगा।

अब, गतिविधि लीक के लिए कुछ डीबगिंग तकनीकों पर। सत्यापित करने के लिए कि अपनी गतिविधि को साफ किया जा रहा है, तो आपकी एप्लिकेशन प्रविष्टि Activity की OnCreate विधि के लिए निम्न कोड जोड़ें:

var vmPolicy = new StrictMode.VmPolicy.Builder(); 
StrictMode.SetVmPolicy (vmPolicy.DetectActivityLeaks().PenaltyLog().Build()); 

यह सक्षम बनाता है StrictMode, एक उपयोगी डिबगिंग उपकरण है जो खुशी से आपको सूचित करता है जब आप संसाधन लीक कर दिया है। आपकी ऐप्लिकेशन गतिविधियों में से एक सही ढंग से जारी नहीं किया है, यह उत्पादन धारा को कुछ इस तरह डंप हो जाएगा:

[StrictMode] class activitydispose.LeakyActivity; instances=2; limit=1 
[StrictMode] android.os.StrictMode$InstanceCountViolation: class activitydispose.LeakyActivity; instances=2; limit=1 
[StrictMode] at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1) 

Dispose() कॉल के साथ इस संयोजन, आप देख सकते हैं कि गतिविधियों को जारी किया जा रहा है। यहां बताया गया है कि आप आम तौर पर Activity और Xamarin में इसके संसाधन कैसे करेंगे।एंड्रॉइड:

protected override void Dispose (bool disposing) 
{ 
    // TODO: Dispose logic here. 
    base.Dispose (disposing); 
    GC.Collect(GC.MaxGeneration); // Will force cleanup but not recommended. 
} 

protected override void OnDestroy() 
{ 
    if (density != null) { // Release Java objects (buttons, adapters etc) here 
     density.Dispose(); 
     density = null; 
    } 
    base.OnDestroy(); 
    this.Dispose(); // Sever java binding. 
} 
+5

"यह वास्तव में उल्लेखनीय जटिल है" <------ कोई भी उत्तर जो इसके साथ शुरू होता है वह एक अच्छा होगा। – rarrarrarrr

+0

यह जानकारी बहुत उपयोगी है। सख्त मोड चट्टानों – xleon

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

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