当前位置: 首页 > 知识库问答 >
问题:

Xamarin(Android)。当电话锁定一段时间后,后台服务停止

国兴文
2023-03-14

我们在让后台服务工作方面遇到了一些麻烦。即使在应用程序关闭和手机锁定的情况下,计时器也应该每秒执行一次代码。只要应用程序打开或在后台,手机正在使用,这就可以正常工作,但当手机被锁定并处于待机状态时,服务会在一段时间后自动停止。

代码是根据以下示例建模的:http://arteksoftware.com/backgrounding-with-xamarin-forms/

        MessagingCenter.Subscribe<StartBackgroundTimer>(this, "StartBackgroundTimer", message =>
        {
            var intent = new Intent(this, typeof(LongRunningTaskService));
            StartService(intent);
        });
        MessagingCenter.Subscribe<StopBackgroundTimer>(this, "StopBackgroundTimer", message =>
        {
            var intent = new Intent(this, typeof(LongRunningTaskService));
            StopService(intent);
        });
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System.Threading;
using System.Threading.Tasks;
using OurAppNamespace.Classes;
using Xamarin.Forms;

namespace OurAppNamespace.Droid
{
[Service]
public class LongRunningTaskService : Service
{
    CancellationTokenSource _cts;

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {

        _cts = new CancellationTokenSource();

        Task.Run(() =>
        {
            try
            {
                    //INVOKE THE SHARED CODE
                    var timer = new BackgroundTimer();
                timer.RunBackgroundTimer(_cts.Token).Wait();
            }
            catch (System.OperationCanceledException)
            {

            }
            finally
            {
                if (_cts.IsCancellationRequested)
                {
                    var message = new BackgroundTimerCancelledMessage();
                    Device.BeginInvokeOnMainThread(
                        () => MessagingCenter.Send(message, "BackgroundTimerCancelledMessage")
                    );
                }
                StopSelf();
            }

        }, _cts.Token);
        return StartCommandResult.Sticky;
    }

    public override void OnCreate()
    {
        base.OnCreate();
    }

    public override void OnDestroy()
    {
        if (_cts != null)
        {
            _cts.Token.ThrowIfCancellationRequested();

            _cts.Cancel();
        }
        base.OnDestroy();
    }
}
}

然后,在PCL中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace OurAppNamespace.Classes
{
public class StartBackgroundTimer { }
public class StopBackgroundTimer { }

public class BackgroundTimerMessage
{

}
public class BackgroundTimerCancelledMessage { }

public class BackgroundTimer
{
    public async Task RunBackgroundTimer(CancellationToken token)
    {
        await Task.Run(async () =>
        {
            while (true)
            {
                token.ThrowIfCancellationRequested();
                await Task.Delay(1000);

                Device.BeginInvokeOnMainThread(() =>
                {
                    MessagingCenter.Send<BackgroundTimerMessage>(new BackgroundTimerMessage(), "BackgroundTimer");
                });
            }
        }, token);
    }
}

}

最后,当BackgroundTimer调用:

    private static void UpdateActiveTimers()
    {
        MessagingCenter.Subscribe<BackgroundTimerMessage>(instance, "BackgroundTimer", message =>
        {
            (unrelated code)
            DependencyService.Get<INotificationHandling>().UpdateTimerNotification(timeText);
            }
        });
    }

当启动定时器10分钟时,用不同的手机有不同的结果。

HOMTOM HT16表现出与黑莓Priv相同的行为,但它在大约30秒后暂停计时器的时间更早。

如何更改代码,使后台服务在手机锁定Hibernate时在所有设备上成功运行?

提前感谢!

共有1个答案

胥玮
2023-03-14

我要感谢SushiHangover的评论,使用前台服务(->将现有服务提升为前台服务)解决了这个问题。

 类似资料:
  • 触发spring boot REST服务后,该服务可以正常运行数小时,所有请求都可以正常工作,没有任何问题。发生的是,一段时间后,它随机地停止了。在查看日志时,我没有发现任何错误,除了应用程序已被销毁的信息。 一段时间后的日志 Maven依赖项 对于为什么spring boot REST API可能会停止有什么想法吗?我的maven依赖关系是根据演示的--而且它正在成功运行--这就是为什么服务在随

  • 我有6个集装箱在码头群中运行。Kafka Zookeeper、MongoDB、A、B、C和接口。接口是来自公共的主要访问点-只有这个容器发布端口-5683。接口容器在启动期间连接到A、B和C。我使用docker组合文件docker堆栈部署,每个服务都有一个名称,用作接口的主机。一切都开始顺利,运转良好。过了一段时间(20分钟、1小时……),我无法向接口提出请求。接口接收到我的请求,但应用程序与服务

  • 问题内容: 我有一个媒体播放器服务,可在整个应用程序的后台播放音乐,例如: 问题在于,当用户更改应用程序或进入手机主屏幕(应用程序在后台运行)时,音乐仍在播放。 我试图停止它和方法,但是当我更改活动时这会停止音乐,这是我不希望的(我希望音乐在用户浏览活动时继续播放)。 更新资料 我尝试了广播: 我加了 在音乐服务的onCreate和接收事件的方法中: 在应用程序类中,我这样做: 但是音乐不会恢复

  • 如何在Android奥利奥继续后台服务而不显示通知点?我使用通知继续我的后台服务,但我不想显示运行服务的通知。

  • 当用户使用后退按钮退出应用程序时,Android中的后台服务将停止运行。如果应用程序在前台或后台(点击HOME按钮),同样的服务工作得很好。 有3个案例: null MainActivity.java SimpleService

  • 问题内容: 我有一个可以存储对象列表的swing应用程序。当用户单击按钮时, 我想对列表中的每个对象执行两项操作,然后完成操作,然后在JPanel中绘制结果图。我一直在尝试SwingWorker,Callable和Runnable进行处理,但是无论我做什么,在处理列表(由于绑定到IO最多可能需要几分钟的时间)时,GUI都被锁定了。 我感觉这可能是我调用线程或某种方式的方式,或者可能与图形功能有关?