Xamarin Android终结者离开活动去其他活动时没有得到调用

终结者在离开活动之后永远不会被调用。 这是否意味着即使我开始下一个活动,活动仍然存在。

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); } } } 

Solutions Collecting From Web of "Xamarin Android终结者离开活动去其他活动时没有得到调用"

这实际上非常复杂, 关于仍然活着的活动的简短答案是肯定的,不是。 如果您已经正确清理了Activity的资源,那么您的活动将被垃圾收集器清理(最终)。

关于清理,重要的是要知道, Xamarin不鼓励使用终结器(从幻灯片44开始) 。 原因如下:

  • 他们不能保证在最后期限内运行。
  • 他们不按照特定的顺序运行。
  • 他们使物体寿命更长。
  • GC不知道非托pipe资源。

因此,使用终结器执行清理是做事情的错误方法…如果要确保MainActivity被销毁,请将Activity置于其OnDestroycallback中:

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

这将导致Mono在下一次垃圾回收循环( GC.Collect(GC.MaxGeneration) )期间中断对等连接并销毁活动。 从文档:

为了缩短对象的生命周期,应该调用Java.Lang.Object.Dispose()。 这将通过释放全局引用来手动“断开”两个VM之间的对象上的连接,从而允许更快地收集对象。

请注意那里的调用顺序, 必须在调用返回到Android Land的任何代码之后调用this.Dispose() 。 为什么? Java和.NET之间的所有连接现在都被打破,以允许Android回收资源,所以任何使用Android-land对象(Fragment,Activity,Adapter)的代码都将失败。

现在,到一些debugging技术的活动泄漏。 要validation您的活动是否正在清理,请将以下代码添加到应用程序条目ActivityOnCreate方法中:

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

这使得StrictMode成为一个有用的debugging工具,可以在泄露资源时高兴地通知您。 当你的一个应用程序的活动没有正确的发布,它会把这样的东西转储到输出stream:

 [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()调用,你可以检查活动是否被释放。 下面是你通常如何在Xamarin.Android中的Activity及其资源:

 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. }