在Android上使用Xamarin.Forms运行无限运行后台任务

时间:2016-12-12 11:58:24

标签: c# android multithreading xamarin

我的问题如下:

我正在尝试在服务中运行无限后台任务,该任务应该在Android上启动时启动。 (此任务用于频繁检查网站上的json文件是否有变化。)显然,在后台服务(由BroadcastReceiver执行)中运行任务是不可能的,因为线程似乎无休止地等待UI;因此,只有在启动UI时,此任务才会运行。

这是我尝试这个时在logcat中发生的事情:

Waited long enough for ServiceRecord <Name of Service>

在任务之外运行某些东西,但不在内部。 那么:有没有办法做这样的事情:

  • 在BOOT_COMPLETED上运行BroadcastReceiver
  • 在BroadcastReceiver
  • 中运行服务
  • 启动无限任务应用程序独立

服务

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");
        }
    }
}

0 个答案:

没有答案