且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

仅当应用程序打开并运行时如何在后台运行方法?

更新时间:2022-12-27 11:40:37

我们在表单应用程序中所做的是利用 System.Diagnostics 和 Xamarin.Forms 中可用的 Device.Timer 和 Stopwatch 类来创建一个非常通用的托管计时器,我们可以使用 Xamarin.Forms 中的 onStart、onSleep 和 onResume 方法与之交互.

What we did in our forms application was to make use of the Device.Timer and the Stopwatch class that available in System.Diagnostics, and Xamarin.Forms to create a very generic managed timer that we could interact with using the onStart, onSleep and onResume methods in Xamarin.Forms.

这个特殊的解决方案不需要任何特殊的平台特定逻辑,并且设备计时器和秒表是非 UI 阻塞的.

This particular solution doesn't require any special platform specific logic, and the device timer and stopwatch are non UI blocking.

using Xamarin.Forms;
using System;
using System.Linq;
using System.Diagnostics;

namespace YourNamespace
{
    public partial class App : Application
    {
        private static Stopwatch stopWatch = new Stopwatch();
        private const int defaultTimespan = 1;

        protected override void OnStart()
        {
            // On start runs when your application launches from a closed state, 

            if (!stopWatch.IsRunning)
            {
                stopWatch.Start();
            }

            Device.StartTimer(new TimeSpan(0, 0, 1), () =>
            {
                // Logic for logging out if the device is inactive for a period of time.

                if (stopWatch.IsRunning && stopWatch.Elapsed.Minutes >= defaultTimespan)
                {
                    //prepare to perform your data pull here as we have hit the 1 minute mark   

                        // Perform your long running operations here.

                        Device.InvokeOnMainThread(()=>{
                            // If you need to do anything with your UI, you need to wrap it in this.
                        });

                    stopwatch.Restart();
                }

                // Always return true as to keep our device timer running.
                return true;
            });
        }

        protected override void OnSleep()
        {
            // Ensure our stopwatch is reset so the elapsed time is 0.
            stopWatch.Reset();
        }

        protected override void OnResume()
        {
            // App enters the foreground so start our stopwatch again.
            stopWatch.Start();
        }
    }
}



提供有关上述解决方案如何逐步工作的一些背景信息:

To give some context as to how the above solution works step by step:

应用程序从关闭状态开始,'OnStart()' 方法创建我们的 Device.Timer,它每秒滴答一次.它还可以启动计时一分钟的秒表.

The application starts from a closed state and the 'OnStart()' method creates our Device.Timer that ticks every second. It also starts our stopwatch that counts upto a minute.

当应用程序进入后台时,如果我们将false"值传递给我们的 Device.StartTimer() 操作,它此时会触发OnSleep"方法,它不会再次启动.因此,我们只需重置秒表,以备再次打开应用程序时使用.

When the app goes into the background it hits the 'OnSleep' method at this point if we were to pass a 'false' value into our Device.StartTimer() action it would not start up again. So instead we simply reset our stopwatch ready for when the app is opened again.

当应用返回前台时,它会触发OnResume"方法,该方法只会启动现有的秒表.

When the app comes back into the foreground it hits the 'OnResume' method, which simply starts the existing stopwatch.

2018 年

即使在 2018 年,这个答案仍然有一些优点,但主要是针对非常特殊的情况.即使在 Xamarin.Forms 中,也有更好的特定于平台的方法来复制此功能.考虑到用户活动/不活动,上述仍然是一段时间后执行任务的平台不可知方式.

This answer still has some merits even in 2018, but mainly for very specific situations. There are better platform specific ways to replicate this functionality even in Xamarin.Forms. The above still remains a platform agnostic way to perform a task after a period of time, taking into account user activity/inactivity.