.NET MAUI 循环后台作业每天运行几次

问题描述 投票:0回答:2

我希望有一个后台作业每天运行 2-3 次,但更少也没关系。这只是对我的服务器的快速 api 调用,不需要更新 UI,事实上我更喜欢它在应用程序不在前台时运行,但这是另一个主题。

我读到最新版本的 Android 和 iOS 甚至制造商限制了该应用程序,但我不需要这些任务精确地在某个时间执行。 我不确定对于 Android 是否应该使用 JobScheduler 或 WorkManager,对于 iOS 是否应该使用 BackgroundFetch 或 BackgroundTask。

假设该任务每天应运行 3 次,即大约每 8 小时运行一次。 问题是用户可能不会再次打开应用程序,因此应该将任务安排为重复执行,也许每次运行时都可以安排另一个任务,但如果一个任务失败,则永远无法到达该行。

我不需要支持旧的操作系统版本,只需要支持iOS 15+和Android api 30+。

谢谢您的帮助!

android ios xamarin background-process maui
2个回答
0
投票

苹果对于App占用的硬件资源要求严格,更不用说处于后台状态的App了。当App进入后台状态时,它很快就会被操作系统暂停,除非你向操作系统申请许可。只能允许几种模式在后台运行,见下图

您想要一个后台 cron 作业,这在 iOS 中是不允许的。

对于 Andriod,您知道我们可以使用 WorkManager 或 JobSchedule。以下是一些您可以参考的文档:

WorkManager 入门

Android 作业调度程序

希望它对你有用。


0
投票

你应该能够做这样的事情,但我无法让它工作。

将其添加到 info.plist。

告诉应用程序允许后台获取和后台处理。

<key>UIBackgroundModes</key>
  <array>
    <string>fetch</string>
    <string>processing</string>
  </array>

告诉应用程序允许执行任务。

<key>BGTaskSchedulerPermittedIdentifiers</key>
  <array>
    <string>com.yourappname.upload</string>
    <string>com.yourappname.refresh</string>
  </array>

将它们注册为 AppDelegate 中的变量。

    public static string UploadTaskId { get; } = "com.yourappname.upload";
    
    public static string RefreshTaskId { get; } = "com.yourappname.refresh";

在您的 AppDelegate FinishedLaunching 方法中注册它。

    BGTaskScheduler.Shared.Register(UploadTaskId, null, task => HandleUpload(task as BGProcessingTask));
    BGTaskScheduler.Shared.Register(RefreshTaskId, null, task => HandleAppRefresh(task as BGAppRefreshTask));

现在它应该每隔一段时间调用这个方法。

private void HandleUpload(BGTask task)
    {
        SentrySdk.CaptureMessage("BGTaskScheduler HandleUpload = " + "yes");

        ProcessData(); //or something like this
        task.SetTaskCompleted(true);
    }

它也应该每隔一段时间调用这个方法。

private void HandleAppRefresh(BGAppRefreshTask task)
    {

        SentrySdk.CaptureMessage("BGTaskScheduler HandleAppRefresh = " + "yes");

        task.ExpirationHandler = () =>
        {            
            var refresh = new BGAppRefreshTaskRequest(RefreshTaskId);
            BGTaskScheduler.Shared.Submit(refresh, out NSError refreshError);

            if (refreshError != null)
                //Console message
        };

        HandleUpload(task);
    }

我什至从 ProcessData() 和 DidEnterBackground 重写方法中调用此方法。

private void ScheduleUpload()
    {
        SentrySdk.CaptureMessage("BGTaskScheduler ScheduleUpload = " + "yes");

        Console.WriteLine("ScheduleUpload");

        var startDate = DateTime.Now.AddMinutes(10);

        var upload = new BGProcessingTaskRequest(UploadTaskId)
        {
            RequiresNetworkConnectivity = true,
            RequiresExternalPower = false,
            EarliestBeginDate = (NSDate)startDate
        };

        BGTaskScheduler.Shared.Submit(upload, out NSError error);

        var refresh = new BGAppRefreshTaskRequest(RefreshTaskId);
        BGTaskScheduler.Shared.Submit(refresh, out NSError refreshError);

        if (error != null)
            Console.WriteLine($"Could not schedule BGProcessingTask: {error}");
        if (refreshError != null)
            Console.WriteLine($"Could not schedule BGAppRefreshTask: {refreshError}");
    }
© www.soinside.com 2019 - 2024. All rights reserved.