离开活动后永远不会调用终结器。这是否意味着即使我继续进行下一个活动,活动仍然存在。
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);
}
}
}
答案 0 :(得分:28)
这实际上非常复杂;关于活动仍在存在的简短回答是肯定的,不是。如果您已正确清理了Activity
的资源,您的活动将被垃圾收集器清理(最终)。
关于清理,要知道Xamarin discourages (slide 44 onwards)使用终结器进行清理。这就是原因:
- 不保证在任何截止日期内运行。
- 他们不按特定顺序跑。
- 他们让对象活得更久。
- GC不了解非托管资源。
因此,使用终结器执行清理是错误的处理方式...如果要确保销毁MainActivity
,请手动处理Activity
OnDestroy
{ {1}}回调:
protected override void OnDestroy ()
{
base.OnDestroy ();
this.Dispose (); // Sever java binding.
}
这将导致Mono在下一个垃圾收集周期(GC.Collect(GC.MaxGeneration)
)中破坏peer object连接并销毁活动。来自文档:
要缩短对象的生命周期,应调用Java.Lang.Object.Dispose()。这将手动&#34;切断&#34;通过释放全局引用来连接两个VM之间的对象,从而允许更快地收集对象。
请注意那里的通话顺序,{/ 1}} 必须在任何调用回Android版本的代码后调用。为什么? Java和.NET之间的所有连接现在都被破坏,以允许Android回收资源,因此任何使用Android-land对象(Fragment,Activity,Adapter)的代码都将失败。
现在,介绍一些Activity泄漏的调试技巧。要验证您的活动是否正在清理,请将以下代码添加到您的应用条目this.Dispose()
的{{1}}方法中:
OnCreate
这使StrictMode
成为一种有用的调试工具,可以在您泄露资源时愉快地通知您。如果您的某个应用活动未正确发布,它会将类似内容转储到输出流:
Activity
将此与var vmPolicy = new StrictMode.VmPolicy.Builder ();
StrictMode.SetVmPolicy (vmPolicy.DetectActivityLeaks().PenaltyLog().Build ());
调用相结合,您可以检查是否正在发布活动。以下是您在Xamarin.Android中通常[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()