我的问题如下:
我正在尝试在服务中运行无限后台任务,该任务应该在Android上启动时启动。 (此任务用于频繁检查网站上的json文件是否有变化。)显然,在后台服务(由BroadcastReceiver执行)中运行任务是不可能的,因为线程似乎无休止地等待UI;因此,只有在启动UI时,此任务才会运行。
这是我尝试这个时在logcat中发生的事情:
Waited long enough for ServiceRecord <Name of Service>
在任务之外运行某些东西,但不在内部。 那么:有没有办法做这样的事情:
服务
using Android.App;
using Android.Content;
using Android.OS;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms;
using <MyPackage>.services;
namespace <MyPackage>.Droid
{
[Service]
public class BackgroundService : Service
{
CancellationTokenSource _cts;
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
base.OnStartCommand(intent, flags, startId);
_cts = new CancellationTokenSource();
Task.Run(() => {
try
{
//Invoke Task
var process = new BackgroundDataWatcher();
process.StartWatcherAsync(_cts.Token).Wait();
}
catch (Android.OS.OperationCanceledException)
{
}
finally
{
if (_cts.IsCancellationRequested)
{
var message = new CancelledMessage();
Device.BeginInvokeOnMainThread(
() => MessagingCenter.Send(message, "CancelledMessage")
);
}
}
}, _cts.Token);
StartForeground((int)NotificationFlags.ForegroundService, new Notification(Resource.Drawable.notification," ist aktiv..."));
return StartCommandResult.Sticky;
}
public override void OnDestroy()
{
if (_cts != null)
{
_cts.Token.ThrowIfCancellationRequested();
_cts.Cancel();
}
base.OnDestroy();
}
}
public class CancelledMessage{}
}
接收机
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using static <MyPackage>.services.BackgroundDataWatcher;
using Android.Util;
namespace <MyPackage>.Droid
{
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class StartReceiver : BroadcastReceiver
{
private static int notificationId = 0;
private static String TAG = "StartReceiver";
public override void OnReceive(Context context, Intent intent)
{
Log.Info(TAG,"Receiver started!");
Log.Info(TAG,"Adding NotificationMessage");
//Register Service for Notifications.
MessagingCenter.Subscribe<NotificationMessage>(this, "NotificationMessage", message => {
Notification.Builder builder = new Notification.Builder(context)
.SetContentTitle(message.Header)
.SetContentText(message.Message)
.SetAutoCancel(message.IsRemoveable)
.SetSmallIcon(Resource.Drawable.notification);
if (message.InformUser)
builder.SetDefaults(NotificationDefaults.All);
// Build the notification:
Notification notification = builder.Build();
// Get the notification manager:
NotificationManager notificationManager =
context.GetSystemService(Context.NotificationService) as NotificationManager;
// Publish the notification:
notificationId++;
notificationManager.Notify(message.Notificationid != 0 ? message.Notificationid : notificationId, notification);
});
Log.Info(TAG,"Creating intent.");
Intent timerIntent = new Intent(context, typeof(BackgroundService));
timerIntent.AddFlags(ActivityFlags.NewTask);
timerIntent.SetAction("ReminderService.ACTION_RESCHEDULE");
Log.Info(TAG,"Start Service.");
context.StartService(timerIntent);
Log.Info(TAG,"All done");
}
}
}