Xamarin Android Finalizer не получает вызов, когда вы покидаете активность, чтобы перейти на другую активность

Финализатор никогда не вызывается после выхода из игры. Означает ли это, что активность еще жива, хотя я перешел к следующему действию.

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 Finalizer не получает вызов, когда вы покидаете активность, чтобы перейти на другую активность"

Это на самом деле удивительно сложно; Короткий ответ, касающийся активности, которая еще жива, да и нет. Если вы правильно очистите ресурсы для своей Activity , ваша деятельность будет очищена (в конечном счете) сборщиком мусора.

Что касается очистки, им важно знать, что Xamarin не поощряет (слайд 44) с использованием финализаторов. Вот почему:

  • Они не гарантируются в течение какого-либо срока.
  • Они не работают в определенной последовательности.
  • Они заставляют объекты жить дольше.
  • GC не знает о неуправляемых ресурсах.

Поэтому использование финализатора для выполнения очистки – это неправильный способ делать вещи … Если вы хотите, чтобы MainActivity был уничтожен, вручную MainActivity Activity в его MainActivity OnDestroy :

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

Это заставит Моно разорвать соединение с одноранговым объектом и уничтожить действие во время следующего цикла сбора мусора ( GC.Collect(GC.MaxGeneration) ). Из документов:

Чтобы сократить время жизни объекта, необходимо вызвать Java.Lang.Object.Dispose (). Это будет вручную «разорвать» соединение на объекте между двумя виртуальными машинами, освободив глобальную ссылку, что позволит быстрее собирать объекты.

Обратите внимание на порядок вызова там, this.Dispose() должен быть вызван после любого кода, который вызывается обратно на Android- this.Dispose() . Зачем? Все соединения между Java и .NET теперь сломаны, чтобы позволить Android восстановить ресурсы, поэтому любой код, который использует объекты Android-land (Fragment, Activity, Adapter), не удастся.

Теперь, на некоторые методы отладки для утечек активности. Чтобы проверить, что ваша деятельность очищается, добавьте следующий код в метод OnCreate для входа в ваши приложения. Activity :

 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() , вы можете проверить, что действия освобождаются. Вот как вы обычно делали и свои ресурсы в Xamarin.Android:

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