C# 报警管理器运行的代码在1分钟后消失
我有一些代码需要(大约)5分钟才能运行。这段代码应该定期运行,所以我使用内置的C# 报警管理器运行的代码在1分钟后消失,c#,android,xamarin,C#,Android,Xamarin,我有一些代码需要(大约)5分钟才能运行。这段代码应该定期运行,所以我使用内置的AlarmManager调用它 像这样: public void setAlarm(Context context) { AlarmManager am = (AlarmManager)context.GetSystemService(Context.AlarmService); Intent i = new Intent(context, typeof(keyboardservice.alarmrec
AlarmManager
调用它
像这样:
public void setAlarm(Context context)
{
AlarmManager am = (AlarmManager)context.GetSystemService(Context.AlarmService);
Intent i = new Intent(context, typeof(keyboardservice.alarmreciever));
PendingIntent pi = PendingIntent.GetBroadcast(context, 0, i, PendingIntentFlags.CancelCurrent);
am.SetRepeating(AlarmType.ElapsedRealtimeWakeup, 0, 1000 * 60 * 30, pi); // Millisec * Second * Minute
}
正如您所看到的,代码应该每30分钟运行一次
AlarmService
看起来像这样:
[BroadcastReceiver(Enabled = true)]
public class alarmreciever : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Task.Delay(1000 * 300).Wait();
}
}
我已经简化了上面的代码,但是结果是相同的,代码在1分钟后就消失了(准确地说),就像有一些限制一样
屏幕是开着还是关着都无所谓
我错过了什么
AlarmService看起来像这样
这不是服务
。这是一个广播接收器
我错过了什么
首先,您的BroadcastReceiver
正试图占用主应用程序线程五分钟。即使这是可能的,这也是一个非常糟糕的主意,因为这意味着你的UI在这五分钟内会被冻结。但是,这是不可能的,因为看门狗应该在ANR超时期间(后台工作IIRC为10-15秒)终止您的工作
其次,一般来说,在安卓8.0+上,在后台做任何事情都不能超过一分钟。也有例外情况,特别是如果使用作业调度器
,您有大约10分钟的时间
如果您确信您的工作将在10分钟内完成,那么如果您的minSdkVersion
为21或更高,请切换到JobScheduler
。如果您的minSdkVersion
低于21,至少在那些较旧的设备上,让您的BroadcastReceiver
启动JobIntentService
,您是否在onHandleWork()
中完成了五分钟的工作
请注意,我不知道Xamarin已将其中的哪些内容化,因为我不使用Xamarin
AlarmService看起来像这样
这不是服务
。这是一个广播接收器
我错过了什么
首先,您的BroadcastReceiver
正试图占用主应用程序线程五分钟。即使这是可能的,这也是一个非常糟糕的主意,因为这意味着你的UI在这五分钟内会被冻结。但是,这是不可能的,因为看门狗应该在ANR超时期间(后台工作IIRC为10-15秒)终止您的工作
其次,一般来说,在安卓8.0+上,在后台做任何事情都不能超过一分钟。也有例外情况,特别是如果使用作业调度器
,您有大约10分钟的时间
如果您确信您的工作将在10分钟内完成,那么如果您的minSdkVersion
为21或更高,请切换到JobScheduler
。如果您的minSdkVersion
低于21,至少在那些较旧的设备上,让您的BroadcastReceiver
启动JobIntentService
,您是否在onHandleWork()
中完成了五分钟的工作
请注意,我不知道Xamarin已将其中的哪些内容化,因为我不使用Xamarin。解决方法是:
new Task(() =>
{
DoAction(context);
}).Start();
解决方法:
new Task(() =>
{
DoAction(context);
}).Start();