当app被杀死时,Xamarin表单后台服务被杀死

时间:2017-08-01 11:03:02

标签: c# xamarin.forms android-service background-service

我在我的xamarin表单项目中使用Prism。我也在使用后台服务在后台推送长时间运行的任务。问题是当应用程序被杀死时服务也被杀死。并且“被杀” “我的意思是按主页按钮 - >查看所有正在运行的应用 - >把我的应用放在一边 - >即使应用程序被杀,我也希望保持服务的活力。我已经阅读了很多帖子,说它可以完成。但是我无法让它工作。 这就是我的尝试: -

这是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方法中使用Alarm Manager,当应用程序根据其文档被杀时会被触发。但在我的情况下,服务不会重新启动atall.Can有人指出我的代码中有什么错误?或者提供一个可行的解决方案,以便我可以在我的应用中实现它。 提前致谢!

1 个答案:

答案 0 :(得分:0)

调用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会在您的应用被杀后安排您的服务被杀死。这样做会删除该计划任务。