Фоновая служба форм Xamarin завершается после завершения работы приложения

Я использую Prism в своем проекте форм xamarin. Я также использую фоновые службы для запуска длительных задач в фоновом режиме. Проблема в том, что когда приложение убито, служба также убита. И под "убитым" я имею в виду нажмите кнопку домой -> просмотреть все запущенные приложения -> смахните мое приложение в сторону -> приложение убито. Я хочу, чтобы служба оставалась работоспособной, даже если приложение было убито. Я прочитал много сообщений, в которых говорится, что это можно сделать. не смог заставить его работать. Вот что я пробовал: -

Это Android MainActivity.cs

protected override void OnCreate(Bundle bundle)
        {

            base.OnCreate(bundle);
            try
            {

                global::Xamarin.Forms.Forms.Init(this, bundle);

                LoadApplication(new App(new AndroidInitializer()));
                WireUpLongRunningTask(); 

            }
            catch(Exception)
            {

            }
        }

        public void WireUpLongRunningTask()  
        {
            MessagingCenter.Subscribe<StartSyncBackgroundingTask>(this, "StartSyncBackgroundingTask", message => {
                var intent = new Intent(this, typeof(AndroidSyncBackgroundService));
                StartService(intent);
            });


        }

Это класс AndroidSyncBackgroundService: -

    [Service]
    public class AndroidSyncBackgroundService : Service
    {
        CancellationTokenSource _cts;
        private ISyncBackgroundService _isyncBackgroundService;
        private App _app => (App)Xamarin.Forms.Application.Current;
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            _cts = new CancellationTokenSource();

            Task.Run(() => {
                try {
                    //INVOKE THE SHARED CODE
                    _isyncBackgroundService = _app.Container.Resolve<ISyncBackgroundService>();
                   _isyncBackgroundService.RunBackgroundingCode(_cts.Token).Wait();


                }
                catch (System.OperationCanceledException) {
                }
                finally {
                    if (_cts.IsCancellationRequested) {
                        var message = new CancelledTask();
                        Device.BeginInvokeOnMainThread(
                            () => MessagingCenter.Send(message, "CancelledTask")
                        );
                    }
                }

            }, _cts.Token);

            return StartCommandResult.Sticky;
        }

        public override void OnDestroy()
        {
            if (_cts != null) {
                _cts.Token.ThrowIfCancellationRequested();

                _cts.Cancel();
            }
            StartService(new Intent("com.xamarin.AndroidSyncBackgroundService"));
            base.OnDestroy();
        }

        public override void OnTaskRemoved(Intent rootIntent)
        {
Intent restartServiceIntent = new Intent(Xamarin.Forms.Forms.Context, typeof(AndroidSyncBackgroundService));
          PendingIntent restartServicePendingIntent = PendingIntent.GetService(Xamarin.Forms.Forms.Context, 1, restartServiceIntent,PendingIntentFlags.OneShot);
            AlarmManager alarmService = (AlarmManager)Xamarin.Forms.Forms.Context.GetSystemService(Context.AlarmService);

         alarmService.Set(
         AlarmType.ElapsedRealtime,
         1000,
         restartServicePendingIntent);
        base.OnTaskRemoved(rootIntent);
    }

}

Это класс SyncBackgroundService: -

public class SyncBackgroundService: ISyncBackgroundService
        {
            private ISqliteCallsService _iSqliteCallsService;
            private IFeedBackSqliteService _feedBackSqliteService;
            private ISettingApiService _isettingApiService;
            private ISettingSqliteService _isettingSqliteService;
            private IWebApiService _iwebApiService;
            private App _app => (App)Xamarin.Forms.Application.Current;

            public async Task RunBackgroundingCode(CancellationToken token)
            {

                _iSqliteCallsService= _app.Container.Resolve<ISqliteCallsService>();
                await Task.Run(async () => {

                    token.ThrowIfCancellationRequested();

                    App.bRunningBackgroundTask = true;


                    await Task.Run(async () =>
                    {
                        await Task.Delay(1);

                        _iSqliteCallsService.ftnSaveOnlineModeXMLFormat("Offline", 0);
                        _iSqliteCallsService.SyncEmployeeTableData();
                        _iSqliteCallsService.SaveOfflineAppCommentData();
                        _iSqliteCallsService.SaveOfflineAdditionToFlowData();
                        await Task.Delay(500);

                        //MessagingCenter.Send<SyncBackgroundService>(this, "StopSyncBackgroundingTask");
                    });

               }, token);
            }

           }
        }

Как видно из фрагмента кода, я использовал StartCommandResult.Sticky, но служба по-прежнему прерывается и не перезапускается. Также я использую диспетчер сигналов тревоги в методе OnTaskRemoved, который запускается, когда приложение убивается в соответствии с его документацией. Но в моем случае служба не перезапускается atall. Может ли кто-нибудь указать, в чем ошибка в моем коде? Или предоставьте рабочее решение, чтобы я мог реализовать его в своем приложении. Заранее спасибо!


person Debasish    schedule 01.08.2017    source источник
comment
Попробуйте отменить запланированные задачи ОС для отключения службы с помощью AlarmManager   -  person bi0phaz3    schedule 01.08.2017
comment
На каком устройстве вы тестируете?   -  person David Wasser    schedule 02.08.2017
comment
Тестировал на Moto E (2-го поколения), планшете I-KALL и Amazon Kindle.   -  person Debasish    schedule 03.08.2017
comment
Вы нашли решение этого?   -  person Noobie3001    schedule 20.09.2018


Ответы (1)


Попробуйте это после вызова StartService

if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
        {

            PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(AndroidSyncBackgroundService )), 0);
            AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(Context.AlarmService);
            alarm.Cancel(pintent);
        }

Причина, по которой это может сработать, заключается в том, что Android планирует, что ваша служба будет убита после того, как ваше приложение будет убито. Это приведет к удалению запланированной задачи.

person bi0phaz3    schedule 01.08.2017
comment
Я реализовал ваш метод в Android MainActivity после запуска службы, и у меня он не работает. Что-то мне не хватает? - person Debasish; 01.08.2017
comment
Служба все еще закрывается, когда ваше приложение закрывается? - person bi0phaz3; 01.08.2017
comment
Также где находится OnCreate в вашем сервисе Android? - person bi0phaz3; 01.08.2017
comment
Служба закрывается, когда я убиваю приложение. - person Debasish; 02.08.2017
comment
OnCreate находится в MainActivity, а не в службе Android. - person Debasish; 02.08.2017