Xamarin - Android - 按钮单击时未从活动堆栈中删除活动

时间:2016-02-23 20:17:25

标签: c# android android-activity xamarin

我有一个使用以下代码调用Activity的服务:

var activityIntent = new Intent(ApplicationContext, typeof(cptChamadaActivity));
                activityIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask | ActivityFlags.NoHistory);
                StartActivity(activityIntent);

在活动的OnCreate方法中,我有那个代码:

base.OnCreate(bundle);

        SetContentView(Resource.Layout.Chamada);

        var simBtn = FindViewById<Button>(Resource.Id.simBtn);
        var naoBtn = FindViewById<Button>(Resource.Id.naoBtn);

        simBtn.Click += (sender, e) => { Finish(); };
        naoBtn.Click += (sender, e) => { Finish(); };

如果我点击 simBtn ,活动会关闭,但不会从活动堆栈中删除,但是,如果我放置了Finish();在OnCreate()中,就像那样:

base.OnCreate(bundle);

        SetContentView(Resource.Layout.Chamada);

        var simBtn = FindViewById<Button>(Resource.Id.simBtn);
        var naoBtn = FindViewById<Button>(Resource.Id.naoBtn);

        simBtn.Click += (sender, e) => { Finish(); };
        naoBtn.Click += (sender, e) => { Finish(); };

        Finish();

活动已从堆叠中移除。 我在我的活动声明中使用 NoHistory = true

知道我缺少什么吗?

2 个答案:

答案 0 :(得分:0)

修改

我误解了这个问题。现在在您对原始问题的评论中,我想我现在正在做。

活动在设备本身的活动堆栈中可见。我认为它是在OnResume之后添加的,因为所有的视图都被夸大等等,这使得它可以在Android上显示它。如果使用Finish();在OnCreate中,视图不可见,因此不会显示在堆栈中。

不用担心,如果你完成了你的活动,即使Android通过堆栈向用户显示活动,活动也会完成。它只是用户返回您应用的一种方式。

您可以通过覆盖OnDestroy并放置断点来确认这一点。如果它被击中,那么你知道活动已经关闭。如果没有,那么看看我的原始答案。

原始回答:

我最近遇到了同样的问题。我几乎完成了我的应用程序,在测试阶段,其他人注意到活动没有被处理掉。因此,在使用该应用程序数小时后,应用程序内存不足并挂起。

问题可能不在于你的OnCreate,而是在OnResume中,因为你将Activity传递给另一个保持对它的引用的对象,因此Activity不被单声道GC处理。但是如果没有OnResume中的代码,我无法100%确定您遇到了同样的问题。

你的例子表现得像你描述的那样是因为当你调用Finish()时;在OnCreate中,永远不会在Android生命周期中调用OnResume(刚刚测试过它)。所以从未发生过Activity泄漏。如果使用Finish();在匿名方法中,OnResume已经运行,其中的代码已经创建了一个Activity泄漏。

如果您希望获得有关代码的更多帮助,请发布您的OnResume代码。

一些提示:

尝试避免使用它,从而将Activity传递给其他对象。如果某个对象需要Context,请使用ApplicationContext而不是此。

如果确实需要将Activity传递给其他对象,请在对象中创建一个WeakReference:

 public class SomeClass
 {
   private WeakReference _weakactivity;
   private Activity _activity
   {
     get { return _weakactivity.Target as Activity; }
     set { _weakactivity = new WeakReference(value); }
   }

   public SomeClass(Activity activity)
   {
     _activity = activity;
   }
 }

该示例将创建一个弱引用,告诉GC在不使用时允许它处理它(我对其工作原理的理解可能是错误的。)

另一个提示是使用Action而不是EventHandlers。你可以使用action = null;丢弃所有事件。如果您仍想使用EventHandlers,请确保在调用OnDestroy之前取消订阅。

有关此观看https://www.youtube.com/watch?v=88ZLgLrwdts

的更多信息

答案 1 :(得分:0)

通过在 base.OnCreate(savedInstanceState) 之后创建一个刚刚完成的简单Activity来管理,然后从我想要的实际Activity中启动它关闭然后完成它。

这是活动:

[Activity]
public class clsExitActivity : Activity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Finish();
    }

    public static void ExitApp(Context ctx)
    {
        var i = new Intent(ctx, typeof(clsExitActivity));
        i.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask | ActivityFlags.ExcludeFromRecents | ActivityFlags.NoAnimation);
        ctx.StartActivity(i);
    }
}

然后使用(来自我想要关闭的活动):

base.Finish();
clsExitActivity.ExitApp(ApplicationContext);

我在另一个问题中找到了 clsExitActivity 的代码,但我再也找不到它来粘贴它的URL了。