【问题标题】:Xamarin (Android). Background service stops after some time when phone lockedXamarin(安卓)。手机锁定一段时间后后台服务停止
【发布时间】:2018-02-19 15:32:27
【问题描述】:

我们无法让后台服务正常工作。即使应用程序关闭并且手机被锁定,计时器也应该每秒执行一次代码。只要应用程序处于打开状态或在后台并且手机正在使用中,此功能就可以正常工作,但是当手机处于锁定状态并处于待机状态时,服务会在一段时间后自动停止。

代码仿照本例:http://arteksoftware.com/backgrounding-with-xamarin-forms/

这段代码在MainActivity中执行:

        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);
        });

这是 LongRunningTaskService 类:

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分钟,不同手机会有不同的结果。

小米红米 Note 3 Pro 可以在应用程序在后台执行此代码并锁定手机 10 分钟(不再测试)。

Blackberry Priv 在后台运行应用程序并锁定手机(然后进入待机状态)大约 2 分钟,然后计时器冻结/通知不再更新,直到手机再次打开(解锁不需要)。

通知显示计时器的剩余时间。当手机被锁定时,计时器似乎暂停并在手机再次解锁时恢复。当手机在计时器上剩余 20 分钟时锁定并在 10 分钟后解锁时,计时器会在大约 18 分钟时恢复计数。

HOMTOM HT16 显示与 Blackberry Priv 相同的行为,但它会在大约 30 秒后更早地暂停计时器。

如何修改代码,让手机在锁屏休眠状态下后台服务在所有设备上都能成功运行?

提前致谢!

【问题讨论】:

  • 非常感谢!我将该服务提升为前台服务,它现在正在运行。这听起来很明显,但我们没有想到。
  • 我在 Xamarin Forms 上遇到了同样的问题。我搜索过类似的东西:没有运气。如果有人能指出我正确的方向,我将不胜感激。谢谢!

标签: android xamarin service background xamarin.forms


【解决方案1】:

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

【讨论】:

  • 你有这方面的例子吗?提前致谢。
【解决方案2】:

您的问题可能与 Android (API 23+) 中新的“打盹”模式有关。它搞乱了所有后台任务。请看这个链接: https://developer.android.com/training/monitoring-device-state/doze-standby.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2015-03-18
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多