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); } } }
- Cómo iniciar sesión en la tienda de componentes Xamarin usando Visual Studio 2013
- No se puede instalar Xamarin.Android.Support.v4
- ¿Es posible conectarse mediante programación a una red Wi-Fi usando Xamarin?
- ¿Cómo puedo cancelar desde Device.StartTimer?
- Reproducir varias canciones con MediaPlayer al mismo tiempo: solo una está jugando
- ¿Cómo ejecutar pruebas de unidad para proyectos de biblioteca de Xamarin (iOS y Android)?
- El atributo no se declara (Android) en los atributos xml básicos
- ¿Cómo puedo decirle a mi jefe de trabajo con Xamarin no lo hará más rápido
- ¿Qué podría estar causando el error "OutputPath propiedad no está establecida para proyecto ProjectName.csproj" en mi proyecto MonoDevelop
- Java.lang.NoClassDefFoundError: android.support.v7.app.AppCompatDelegateImplV14 en Xamarin Android
- Cómo conectar y enviar datos con bluetooth c # Xamarin?
- SetPage (Xamarin.Forms.Page) 'es un error obsoleto - Android
- Xamarin Android Cómo grabar vídeo en segundo plano y enviarlo al servidor mediante FTP
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. }
- Android ListView y OnClickListener: Cómo obtener el elemento seleccionado
- Por qué no hay ningún método para obtener el nombre de recurso de objeto Drawable