Xamarin Android Finalizer no se llama al salir de la actividad para ir a otra Actividad

El Finalizador nunca se llama después de dejar la actividad. ¿Significa eso que la actividad todavía está viva aunque pasé a la siguiente actividad.

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

Esto es realmente muy complicado; La respuesta corta, en cuanto a la actividad sigue siendo vivo, es sí y no. Siempre que haya limpiado correctamente los recursos para su Activity , su actividad será limpiada (eventualmente) por el recolector de basura.

En cuanto a la limpieza, es importante saber que Xamarin desalienta (diapositiva 44 en adelante) con los finalizadores. Este es el por qué:

  • No están garantizados para funcionar dentro de cualquier plazo.
  • No se ejecutan en una secuencia específica.
  • Ellos hacen que los objetos vivan más tiempo.
  • El GC no conoce los recursos no gestionados.

Por lo tanto, utilizar un finalizador para realizar la limpieza es la forma incorrecta de hacer las cosas … Si desea asegurarse de que MainActivity se destruye, deseche manualmente la Activity en su devolución de llamada OnDestroy :

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

Esto hará que Mono rompa la conexión de objeto igual y destruya la actividad durante el siguiente ciclo de recolección de basura ( GC.Collect(GC.MaxGeneration) ). De los documentos:

Para acortar la vida útil del objeto, se debe invocar Java.Lang.Object.Dispose (). Esto "cortará" manualmente la conexión en el objeto entre las dos máquinas virtuales liberando la referencia global, permitiendo así que los objetos sean recolectados más rápidamente.

Observe el orden de llamada allí, this.Dispose() debe ser llamado después de cualquier código que invoca de nuevo a Android. ¿Por qué? Todas las conexiones entre Java y .NET están ahora rotas para permitir que Android recupere recursos para que cualquier código que utilice objetos de Android (Fragmento, Actividad, Adaptador) fallará.

Ahora, en algunas técnicas de depuración de fugas de actividad. Para verificar que se está limpiando la actividad, agregue el siguiente código al método OnCreate de su entrada de aplicaciones Activity :

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

Esto permite a StrictMode , una útil herramienta de depuración que le informa felizmente cuando ha filtrado recursos. Cuando una de sus actividades de aplicaciones no se libera correctamente, volcará algo como esto a la salida de flujo:

 [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) 

Al combinar esto con la llamada Dispose() , puede comprobar que se están publicando las actividades. Aquí es cómo normalmente una Activity y sus recursos en 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. } 
  • Genymotion emulador de Android para Xamarin
  • Simple juego en 2D con Xamarin
  • ¿Cómo puedo usar el cliente ServiceStack con Xamarin.Android Licencia Indie
  • Visual Studio 2015 - Xamarin - Android - Obtener "resource.id no contiene una definición para xxx" cuando intento hacer algo en el archivo .cs
  • Cuál es la diferencia entre Java.Net.Uri y Android.Net.Uri
  • RelativeLayout en el cálculo del ancho de StackLayout
  • Accede a la cabecera de respuesta y al código de estado en la web en la aplicación para Android?
  • "Error: SendFailure (Error al escribir encabezados)"
  • ¿Usa la unidad Xamarin?
  • Cómo reducir el tamaño de código de usuario para una aplicación Xamarin Forms en Visual Studio 2015?
  • Android .axml intellisense no funciona con controles de biblioteca de soporte
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.