【问题标题】:Avoid automatic restart of Service using StartCommandResult.Sticky/NonSticky避免使用 StartCommandResult.Sticky/NonSticky 自动重启服务
【发布时间】:2017-12-25 03:22:06
【问题描述】:

我正在做的是我在 Xamarin.Android 中创建了一个简单的服务,现在它只是发送一个本地推送通知。

在我的主应用程序 (MainActivity) 中,我做了一个检查该服务是否运行的语句。如果没有,我将简单地启动服务,否则我什么都不做。

if (UtilityController.IsServiceRunning(typeof(WidgetService), this) == false)
{
    StartService(new Intent(this, typeof(WidgetService)));
}

这也很好用。这里没有问题。

现在,问题在于我的服务被多次运行。

[Service]
public class WidgetService : Service
{
    public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
    {
        SendPushNotification();
        return StartCommandResult.Sticky;
    }

    //Other functions such as OnBind, OnDestroy etc..
}

在这里,我有一项直截了当的服务。它的唯一目的是在函数SendPushNotification(); 中发送推送通知。

但是,当我使用不同的 StartCommandResult 枚举时,我的 OnStartCommand 函数会以不同的方式触发(我认为这是因为它会重新启动服务):

  • 使用StartCommandResult.Sticky 会使服务在我每次关闭/杀死主应用时自行重启。
  • 使用StartCommandResult.NotSticky 会使服务在我每次启动主应用程序时自行重启。

这是个问题。我希望该服务仅在它仍在运行时运行一次。除非我明确告诉它,否则我不希望它重新启动。

我如何做到这一点?

【问题讨论】:

  • Using StartCommandResult.NotSticky makes the Service restart itself every time I start the main app. 除非被告知,否则服务不会自行启动/重新启动,即 StartService
  • @SushiHangover 显然是这样。
  • 那么您在应用程序的开头调用StartService,服务生命周期:developer.android.com/reference/android/app/…

标签: java c# android xamarin service


【解决方案1】:

根据您提供的信息,发生的情况应该是这样的:

使用StartCommandResult.Sticky 时:正如您所描述的,当您终止服务进程时,服务正在重新启动。但这一次 OnStartCommand 被调用时的意图是空的。

使用StartCommandResult.NotSticky 时:在这种情况下,当您终止进程时服务会停止,但不会删除通知。当您再次启动应用程序时,由于服务未启动,它将从您的活动重新开始。

您可以做什么取决于您对应用程序的期望行为。如果您希望服务在您关闭/终止应用程序时停止,您可以执行以下操作:

[Service]
public class WidgetService : Service
{
    bool isStarted;
    public override StartCommandResult OnStartCommand(Android.Content.Intent 
    intent, StartCommandFlags flags, int startId)
    {
        if (!isStarted)
        {
            SendPushNotification();
            isStarted = true;
        }
        return StartCommandResult.NotSticky;
    }

    //Only will be called if stopWithTask attribute is set to false
    public override void OnTaskRemoved(Intent rootIntent)
    {

        // Remove the notification from the status bar.
        base.OnTaskRemoved(rootIntent);
    }

    public override void OnDestroy()
    {
        // We need to shut things down.
        // Remove the notification from the status bar.
        isStarted = false;
        base.OnDestroy();
    }
}

并在您完成服务或关闭应用程序时停止服务。但是,如果您想保持服务运行,因为您正在显示通知,我建议您将服务设为 foreground service

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 2017-01-26
    • 2014-07-08
    • 2020-10-14
    • 2014-07-03
    • 1970-01-01
    相关资源
    最近更新 更多