2016-09-20 3 views
2

Я делаю это приложение в форматах Xamarin (PCL - ios and android), где я получаю большие данные с сервера (используя httpclient), я показываю прогресс чтобы показать пользователю, что данные извлекаются.Продолжить задачу в iOS в фоновом режиме, если телефон заблокирован

Скажем, пользователь случайно блокирует iphone, это то, что я вижу, что происходит в моем приложении.

  1. Идет к фону. Но после этого приложение, похоже, прекращается.
  2. Разблокируйте телефон, приложение представлено с таким же экраном, который был показан перед разблокировкой, но не фоновый процесс не произошло

Мои запросы (вероятно, потому, что приложение завершается (но, почему приложение завершается)?): 1. Почему приложение не продолжает извлечение данных? Кажется хорошо работать в андроиде. 2. Что на самом деле происходит с задачами после блокировки iphone? 3. Как я могу продолжить выполнение задачи в фоновом режиме в iOS, скажем, я выполняю HTTP-вызов в pcl?

ответ

3

Здесь iOS и Android отличаются. В то время как Xamarin упрощает разработку для обоих, в конце концов они все еще являются приложениями для Android и iOS, которые должны соответствовать правилам этой операционной системы.

В iOS, начиная с версии 9, вы не можете запускать код в фоновом режиме, в отличие от Android, где вы можете. Для iOS вам нужно будет сделать для этого какую-то магию. Существует this blogpost, в котором вы можете следить, что несколько описывает то, что вы хотите сделать.

Он утверждает;

является фоновым термином, который мы используем для процесса позволяют некоторым из Кодекса в нашем приложении, чтобы продолжать выполнять в то время как другое приложение в переднем плане. На iOS, до iOS 9, только одному приложению разрешено выполнять код выполнения. Это называется приложением переднего плана. Если вы не измените свой код, чтобы сообщить iOS, что вы планируете запустить код в фоновом режиме, ваше приложение будет принудительно завершено и удалено из памяти, если ваш код попытается выполнить в фоновом режиме. Android действительно позволяет коду работать в фоновом режиме, но фоновые действия - одна из первых вещей, которые нужно прекратить, если операционной системе требуется больше памяти. Вместо этого на Android мы должны использовать другой специальный класс, называемый службой.

Так что еще раз посмотрим, как вы это сделаете в Android, потому что, если вы сделаете это неправильно, ваша передача также будет прервана.

Для реализации в IOS он использует это:

AppDelegate.cs В файле в проекте IOS, мы будем использовать Messaging Center, чтобы подписаться на Start и Stop сообщения. Для удобства, Я завернул iOS apis в другом классе с именем iOSLongRunningTaskExample. Важными здесь методами для iOS являются UIApplication.SharedApplication.BeginBackgroundTask ("LongRunningTask", OnExpiration) и UIApplication.SharedApplication.EndBackgroundTask (taskId).Это методы, которые говорят iOS, что мы будем запускать код в фоновом режиме и не останавливать наше приложение.

Он затем реализует их, как это:

[Register ("AppDelegate")] 
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 
{ 
    public override bool FinishedLaunching (UIApplication app, NSDictionary options) 
    { 
     MessagingCenter.Subscribe<StartLongRunningTaskMessage> (this, "StartLongRunningTaskMessage", async message => { 
      longRunningTaskExample = new iOSLongRunningTaskExample(); 
      await longRunningTaskExample.Start(); 
     }); 

     MessagingCenter.Subscribe<StopLongRunningTaskMessage> (this, "StopLongRunningTaskMessage", message => { 
      longRunningTaskExample.Stop(); 
     }); 
    } 
} 

public class iOSLongRunningTaskExample 
{ 
    nint _taskId; 
    CancellationTokenSource _cts; 

    public async Task Start() 
    { 
     _cts = new CancellationTokenSource(); 

     _taskId = UIApplication.SharedApplication.BeginBackgroundTask ("LongRunningTask", OnExpiration); 

     try { 
      //INVOKE THE SHARED CODE 
      var counter = new TaskCounter(); 
      await counter.RunCounter(_cts.Token); 

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

     UIApplication.SharedApplication.EndBackgroundTask (_taskId); 
    } 

    public void Stop() 
    { 
     _cts.Cancel(); 
    } 

    void OnExpiration() 
    { 
     _cts.Cancel(); 
    } 
} 

Для деталей взглянуть на пост.

+0

Спасибо за отличное объяснение Джеральд! Можете ли вы сказать мне, есть ли способ полностью остановить выполнение задач, когда я блокирую телефон или приложение переходит в фоновое состояние. Поскольку я узнал теперь, что выборка занимает почти 5 минут, я не хочу делать это в фоновом режиме. Или это нормально? –

+0

Единственное, что вы можете сделать, это обнаружить, что ваше приложение подходит к фону и приостанавливает его или что-то в этом роде. Проверьте события по умолчанию в 'App.xaml.cs'. Я не думаю, что вы можете обнаружить, что устройство заблокировано. Но, возможно, вам это не понадобится, потому что, вероятно, событие для перехода на задний план также называется. –

Смежные вопросы