我正在以Xamarin形式(PCL - ios和android)执行此应用程序,我从服务器获取大数据(使用httpclient),我正在显示进度对话框,向用户显示正在获取数据。
让我们说,用户不小心锁定了iphone,这些是我在我的应用中发现的事情。
我的疑问: 1.为什么应用程序不继续数据获取?似乎在android中工作正常。 2.一旦iPhone被锁定,实际上会发生什么? 3.如何在iOS后台继续执行任务,说我在pcl执行http调用?
答案 0 :(得分:3)
这就是iOS和Android的不同之处。虽然Xamarin使两者都更容易开发,但最终它们仍然只是Android和iOS应用程序,必须遵守该操作系统的规则。
在iOS中,从版本9开始,您无法在后台运行代码,因为您可以在Android中使用代码。对于iOS,你将不得不为此做一些魔术。 您可以遵循this blogpost来描述您想要做的事情。
他说;
背景是我们用于允许某些过程的术语 我们的应用程序中的代码继续执行而另一个应用程序在 前景。在iOS上,在iOS 9之前,只允许使用一个应用程序 一次执行代码。这被称为前台应用程序。如果 您不要更改代码以告诉iOS您计划运行代码 在后台,您的应用程序将被强制终止和删除 如果您的代码尝试在后台执行,则从内存中获取。 Android实际上允许代码在后台活动中运行,但是 后台活动是首先要终止的事情之一 操作系统需要更多内存。相反,在Android上,我们应该 使用另一个称为服务的特殊类。
所以还要再看一下你在Android中如何做到这一点,因为如果你做错了,你的传输也会被中断。
为了在iOS中实现,他使用了这个:
然后他按照这样的方式实现它们:在iOS项目的
AppDelegate.cs
文件中,我们将使用Messaging 中心订阅“开始”和“停止”消息。为了方便, 我已将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 ();
}
}
有关详细信息,请查看帖子。