我正在使用Xamarin.iOS应用程序。我希望我当前正在运行的功能的某些部分也应在后台运行。我有一个System.Timer
,它位于App.cs(Load on start)
中,并在其中一个viewcontroller中添加了TimerElapsed
事件,通过该事件,控件在计时器经过时传递给ViewModel并执行所有功能。
现在,我希望同一功能也可以在后台运行,但是无法思考如何实现它。谁可以帮我这个事?
谢谢。
答案 0 :(得分:0)
最简单的方法是这样
//某些异步方法
await Task.Run(async () =>
{
// Code you want to run asynchronously
});
祝你好运!
如果查询恢复!
答案 1 :(得分:0)
背景(使用主屏幕按钮将应用程序发送到后台时)在IOS中有点复杂。您可以通过多种方式实现
1)beginBackgroundTaskWithExpirationHandler,但是它有时间限制
2)locationUpdate事件-但是使用计时器时,它的效果不是很好。当您需要不时检查某些东西时,它会更加可疑
3)让您成为应用播放器。播放器即使在后台也可以工作
我使用方法3,对我来说效果很好
您需要在plist文件中添加背景音频的权限
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
然后在您的AppDelegate
中,需要修改FinishedLaunching
方法
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
...
var currentSession = AVAudioSession.SharedInstance();
currentSession.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.MixWithOthers);
currentSession.SetActive(true);
...
}
并添加下一部分,我也将其放在AppDelegat
#region Background Work
private BackgroundTask _backgroundTask;
private readonly Lazy<TouchLogger> _logger = new Lazy<TouchLogger>(() => new TouchLogger());
public override void DidEnterBackground(UIApplication uiApplication)
{
base.DidEnterBackground(uiApplication);
startBackgroundTask();
}
public override void WillEnterForeground(UIApplication uiApplication)
{
base.WillEnterForeground(uiApplication);
if (_backgroundTask == null)
{
_backgroundTask = new BackgroundTask(_logger.Value);
}
else if (_backgroundTask.IsRunned)
{
_backgroundTask.Stop();
_logger.Value.Info("Background", "Task stopped");
}
}
private void startBackgroundTask()
{
_logger.Value.Info("Background", "startBackgroundTask() called");
var needBackgroundActivity = true;// if you timer is running set true, if not false
if (needBackgroundActivity)
{
if (_backgroundTask == null)
_backgroundTask = new BackgroundTask(_logger.Value);
_backgroundTask.Start();
_logger.Value.Info("Background", "Task runned");
}
}
private class BackgroundTask
{
private const string EmptySoundFileName = "Sounds/empty";//wav file, I use 4 sec long file with no sound
private TouchLogger _logger;
private AVAudioPlayer _player;
private NSTimer _debugTimer;
public bool IsRunned { get; private set; }
public BackgroundTask(TouchLogger logger)
{
_logger = logger;
}
public void Start()
{
IsRunned = true;
if (_player != null && _player.Playing)
{
Stop();
}
var bundle = NSBundle.MainBundle.PathForResource(EmptySoundFileName, "wav");
var sound = new NSUrl(bundle);
_player = AVAudioPlayer.FromUrl(sound);
_player.NumberOfLoops = -1;
_player.Volume = 0.1f;
_player.PrepareToPlay();
_player.Play();
startDebugTimer();
}
public void Stop()
{
IsRunned = false;
if (_player != null && _player.Playing)
{
_player.Stop();
_player.Dispose();
_player = null;
}
stopTimer(ref _debugTimer);
}
private void startDebugTimer()
{
initAndStartTimer(ref _debugTimer, 5,
() => _logger.Value.Info("Background", "Background is fine!"));
}
private void initAndStartTimer(ref NSTimer timer, int intervalMin, Action action)
{
timer?.Invalidate();
if (action != null)
timer =
NSTimer.CreateRepeatingScheduledTimer(
TimeSpan.FromMinutes(intervalMin),
t => action());
}
private void stopTimer(ref NSTimer timer)
{
timer?.Invalidate();
timer = null;
}
}
#endregion
TouchLogger
-向控制台发送一些消息,以检查背景,您可以将其删除。与_debugTimer
相同,它只平均每5分钟写入一次后台工作人员状态。
如果某件事告诉我,我很久以前就做过,所以可能错过了一些事情