C# 离开活动转到其他活动时未调用Xamarin Android终结器
离开活动后,将永远不会调用终结器。这是否意味着即使我继续进行下一个活动,该活动仍然有效C# 离开活动转到其他活动时未调用Xamarin Android终结器,c#,android,xamarin,finalizer,C#,Android,Xamarin,Finalizer,离开活动后,将永远不会调用终结器。这是否意味着即使我继续进行下一个活动,该活动仍然有效 namespace XamarinTest { [Activity(Label = "XamarinTest", Icon = "@drawable/icon")] public class MainActivity : Activity { private int count = 1; private TextView density; protected override vo
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);
}
}
}
名称空间测试{
[活动(Label=“xamarinest”,Icon=“@drawable/Icon”)]
公共课活动:活动{
私有整数计数=1;
私有文本视图密度;
创建时受保护的覆盖无效(捆绑包){
base.OnCreate(bundle);
//从“主”布局资源设置视图
SetContentView(Resource.Layout.ScreenData);
密度=FindViewById(Resource.Id.density);
var pendingent=新意图();
挂起设置标志(ActivityFlags.ClearTop);
SetClass(这个,typeof(TestActivity));
起始触感(悬垂);
完成();
}
~main活动(){
Console.WriteLine(“调用终结器”);
}
受保护的覆盖无效处置(布尔处置){
如果(处置){
depose();
密度=零;
}
基地。处置(处置);
}
}
}
这实际上非常复杂;关于活动仍处于活动状态的简短回答是“是”和“否”。如果您已正确清理了活动的资源,则垃圾收集器将(最终)清理您的活动
关于清理,知道使用终结器是很重要的。原因如下:
- 它们不保证在任何期限内运行
- 它们不按特定的顺序运行
- 它们使物体寿命更长
- GC不知道非托管资源
因此,使用终结器执行清理是错误的做法。。。如果要确保销毁main活动
,请在其ondestory
回调中手动处理活动
:
protected override void OnDestroy ()
{
base.OnDestroy ();
this.Dispose (); // Sever java binding.
}
这将导致Mono在下一个垃圾收集周期(GC.Collect(GC.MaxGeneration)
)中断连接并销毁活动。从文档中:
要缩短对象生存期,应调用Java.Lang.object.Dispose()。这将通过释放全局引用手动“断开”两个VM之间对象上的连接,从而允许更快地收集对象
注意这里的调用顺序,this.Dispose()
必须在任何调用回Android land的代码之后调用。为什么?Java和.NET之间的所有连接现在都已断开,允许Android回收资源,因此任何使用Android陆地对象(片段、活动、适配器)的代码都将失败
现在,我们来介绍一些活动泄漏的调试技术。要验证是否正在清理您的活动,请将以下代码添加到应用程序条目的活动的OnCreate
方法中:
var vmPolicy = new StrictMode.VmPolicy.Builder ();
StrictMode.SetVmPolicy (vmPolicy.DetectActivityLeaks().PenaltyLog().Build ());
这将启用一个有用的调试工具,当您泄漏资源时,它会很高兴地通知您。如果某个应用程序活动未正确发布,它会将类似以下内容转储到输出流:
[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.
}
“这实际上非常复杂”这个信息非常有用。StrictMode Rocks StrictMode似乎只对活动起作用,我们是否也可以对片段起作用?因为它与StrictMode类似,所以不会显示关于片段的任何泄漏信息。