Я использую 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. Может ли кто-нибудь указать, в чем ошибка в моем коде? Или предоставьте рабочее решение, чтобы я мог реализовать его в своем приложении. Заранее спасибо!