• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

c# - Xamarin 表单后台任务仅在 ios 上打开应用程序时运行

[复制链接]
菜鸟教程小白 发表于 2022-12-13 04:09:01 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

  1. 预期行为
    • ios
      • 当应用最小化且每 5 秒收到通知时。
    • 安卓
      • 当应用最小化且每 5 秒收到通知时。
  2. 实际行为
    • ios
      • 应用最小化并且没有通知进来,打开应用会导致通知每 5 秒进来一次。
    • 安卓
      • 当应用最小化并且每 5 秒收到一次通知时。
        //from app.xaml.cs
        protected override void OnSleep()
            {
                void ScheduleNotification()
                {
                    // Start a timer that runs after 5 seconds.
                    Device.StartTimer(TimeSpan.FromSeconds(5), () =>
                    {
                        System.Threading.Tasks.Task.Factory.StartNew( () =>
                        {
                            // Do the actual request and wait for it to finish.
                             PerformNotification();
                            // Switch back to the UI thread to update the UI
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                // Update the UI
                                // ...
                                // Now repeat by scheduling a new request
                                ScheduleNotification();
                                count++;
                            });
                        }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
        
                        // Don't repeat the timer (we will start a new timer when the request is finished)
                        return false;
                    });
                }
               void PerformNotification()
                {
                    CrossLocalNotifications.Current.Show("title", "body"+ count.ToString());
        
                }
                ScheduleNotification();
            }
        



Best Answer-推荐答案


在 iOS 上,不要求在后台运行的应用程序在后台运行的时间不能超过 10 秒。为了让一些代码在后台运行,您可以在 iOS 和 android 上实现 DependencyService。您可以将以下代码放入 iOS 上的该服务中:

public async Task RunCodeInBackgroundMode(Func<Task> action, string name = "MyBackgroundTaskName")
    {
        nint taskId = 0;
        var taskEnded = false;
        taskId = UIApplication.SharedApplication.BeginBackgroundTask(name, () =>
        {
            //when time is up and task has not finished, call this method to finish the task to prevent the app from being terminated
            Console.WriteLine($"Background task '{name}' got killed");
            taskEnded = true;
            UIApplication.SharedApplication.EndBackgroundTask(taskId);
        });
        await Task.Factory.StartNew(async () =>
        {
            //here we run the actual task
            Console.WriteLine($"Background task '{name}' started");
            await action();
            taskEnded = true;
            UIApplication.SharedApplication.EndBackgroundTask(taskId);
            Console.WriteLine($"Background task '{name}' finished");
        });

        await Task.Factory.StartNew(async () =>
        {
            //Just a method that logs how much time we have remaining. Usually a background task has around 180 seconds to complete. 
            while (!taskEnded)
            {
                Console.WriteLine($"Background task '{name}' time remaining: {UIApplication.SharedApplication.BackgroundTimeRemaining}");
                await Task.Delay(1000);
            }
        });
    }

在 Android 上,您可以使用以下代码:

public async Task RunCodeInBackgroundMode(Func<Task> action, string name = "MyBackgroundTaskName")
        {
            var powerManager = (PowerManager)Application.Context.GetSystemService(Context.PowerService);
            var wakeLock = powerManager.NewWakeLock(WakeLockFlags.Partial,
                                                    name);
            //acquire a partial wakelock. This prevents the phone from going to sleep as long as it is not released.
            wakeLock.Acquire();
            var taskEnded = false;

            await Task.Factory.StartNew(async () =>
            {
                //here we run the actual code
                Console.WriteLine($"Background task '{name}' started");
                await action();
                Console.WriteLine($"Background task '{name}' finished");
                wakeLock.Release();
                taskEnded = true;
            });

            await Task.Factory.StartNew(async () =>
            {
                //just a method to keep track of how long the task runs
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                while (!taskEnded)
                {
                    Console.WriteLine($"Background '{name}' task with wakelock still running ({stopwatch.Elapsed.TotalSeconds} seconds)");
                    await Task.Delay(1000);
                }
                stopwatch.Stop();
            });
        }

在共享项目中,您可以通过以下方式调用这些方法:

var deviceInfoServic = ServiceLocator.Instance.Get<YourService Interface here>();
await deviceInfoServic.RunCodeInBackgroundMode(async () =>
{
    //your code here
});

关于c# - Xamarin 表单后台任务仅在 ios 上打开应用程序时运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49542832/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap