【问题标题】:Xamarin forms background service is killed when app is killed当应用程序被杀死时,Xamarin 表单后台服务被杀死
【发布时间】:2017-08-01 11:03:02
【问题描述】:

我在我的 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);
            }

           }
        }

从代码 sn-p 中可以看出,我使用了 StartCommandResult.Sticky,但服务仍然被终止并且不会重新启动。 我还在 OnTaskRemoved 方法中使用了警报管理器,根据其文档,当应用程序被杀死时会触发该方法。但在我的情况下,服务根本没有重新启动。有人能指出我的代码中的错误是什么吗?或者提供一个可行的解决方案,以便我可以在我的应用程序中实现它。 提前致谢!

【问题讨论】:

  • 尝试使用 AlarmManager 取消预定的操作系统任务以杀死服务
  • 你在什么设备上测试?
  • 我已经在 Moto E(第二代)、I-KALL 平板电脑和亚马逊 Kindle 上进行了测试
  • 您找到解决方案了吗?

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


【解决方案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 会安排在您的应用被终止后终止您的服务。这样做会删除该计划任务。

【讨论】:

  • 我在启动服务后在 Android MainActivity 中实现了您的方法,但它对我不起作用。我缺少什么吗?
  • 当您的应用关闭时服务仍然关闭?
  • 还有你的android服务中的OnCreate在哪里?
  • 当我杀死应用程序时服务关闭。
  • OnCreate 在 MainActivity 中,而不在 Android 服务中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
相关资源
最近更新 更多