最近在做番茄钟的功能。首先简单介绍一下番茄钟吧,就是25分钟工作番茄工作法。先说一下** 番茄工作法 **:

番茄工作法是简单易行的时间管理方法,是由弗朗西斯科·西里洛于1992年创立的一种相对于GTD更微观的时间管理方法。
使用番茄工作法,选择一个待完成的任务,将番茄时间设为25分钟,专注工作,中途不允许做任何与该任务无关的事,直到番茄时钟响起,然后在纸上画一个X短暂休息一下(5分钟就行),每4个番茄时段多休息一会儿。
番茄工作法极大地提高了工作的效率,还会有意想不到的成就感。

那么功能就相当于一个25分钟的闹钟,可以播放背景音乐,到点给用户提醒。

功能听起来很简单是不是?其实挺多坑的。

开发过程中遇到了2个问题。

  1. 因为番茄钟是25分钟,那么当用户开启番茄钟后很可能在中途就将APP切换到了后台,那么几分钟程序就会被系统kill掉。
  2. 当用户开启番茄钟的背景音乐时,APP切换到后台或者锁屏状态时,音乐都会立即停止播放。

OK,下面我们一步一步来分析并解决这两个问题。

** 首先要理解iOS系统的后台机制 **

我们都知道,苹果对APP占用硬件资源管的很严,更不要说应用后台时候的资源占用了。正常情况下,使用应用时,APP从硬盘加载到内存,开始工作;当用户按下home键,APP便被挂起,依然驻留在内存中,这种状态下,不调用苹果已开放的几种后台方法,程序便不会运行;如果在这个时候,使程序继续运行,则为后台状态;如果当前内存将要不够用时,系统会自动把之前挂起状态下的APP请出内存。所以我们看到,有些时候打开APP时,还是上次退出时的那个页面那些数据,有时则是重新从闪屏进入。

iOS系统后台机制大概可以分为5种状态

  • Not Running:APP没有启动,也没有后台运行。
  • Active:用户正在使用APP,比如说我们聊微信看网页的时候,APP就处于Active状态。
  • Inactive:这是一个过渡的状态,APP虽然打开了,但是用户没有跟APP有任何互动操作。
  • Background:APP在后台运行,微信会在没有打开的时候接收消息。
  • Suspended:APP虽然在后台运行,但是处于休眠状态,只占用一点内存。

** 那么我需要的是Background模式。即APP在后台运行同时保持程序active的状态 **

首先去xCode里面设置。到info.plist中添加以下信息:

然后到Capabilities里面打开后台模式,并根据项目的要求勾选对应的功能。我这里只需要保持后台运行并且播放背景音乐及通知功能。所以就勾选了第一个和最后一个

以上这两步是告诉系统我这个APP支持后台模式,对应的环境为音频环境。

可是到这一步,APP还是不能长时间运行到后台。

为什么?我们思考一下。我们让程序支持了后台运行的模式。那么我们是不是还需要系统知道我们的程序要在后台运行多久呢?我们需要告诉系统我们期望APP在后台存活的时间。

首先声明一个属性

 @property (nonatomic, assign) UIBackgroundTaskIdentifier bgTask;

在进入后台的时候通过AppDelegate里面的方法:

-(void)applicationDidEnterBackground:(UIApplication *)application{[ self comeToBackgroundMode];
}-(void)comeToBackgroundMode{//初始化一个后台任务BackgroundTask,这个后台任务的作用就是告诉系统当前app在后台有任务处理,需要时间UIApplication*  app = [UIApplication sharedApplication];self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{[app endBackgroundTask:self.bgTask];self.bgTask = UIBackgroundTaskInvalid;}];//开启定时器 不断向系统请求后台任务执行的时间self.timer = [NSTimer scheduledTimerWithTimeInterval:25.0 target:self selector:@selector(applyForMoreTime) userInfo:nil repeats:YES];[self.timer fire];
}-(void)applyForMoreTime {//如果系统给的剩余时间小于60秒 就终止当前的后台任务,再重新初始化一个后台任务,重新让系统分配时间,这样一直循环下去,保持APP在后台一直处于active状态。if ([UIApplication sharedApplication].backgroundTimeRemaining < 60) {[[UIApplication sharedApplication] endBackgroundTask:self.bgTask];self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{[[UIApplication sharedApplication] endBackgroundTask:self.bgTask];self.bgTask = UIBackgroundTaskInvalid;}];}
}

现在就可以让我们的APP一直运行在后台啦!总结下来的思路就是:通过一个后台任务(这个任务我们也不用管,它存在的意义就是和系统去请求后台运行的一定的时间),这个时间我们不知道也不用去管,我们可以通过该时间还剩下多少判断是否继续请求时间,如此循环,我们就可以不断的请求时间来保持我们的app一直运行在后台。

接下来解决音乐在后台模式(切换到后台或者锁屏状态)下停止播放的问题。

其实很简单。

//设置后台模式和锁屏模式下依然能够播放
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];//初始化播放器和两个音频(一个有声 一个无声)
NSURL *urlSound = [[NSURL alloc]initWithString:[[NSBundle mainBundle]pathForResource:@"pomodoSound" ofType:@"m4a"]];
playerSound = [[AVAudioPlayer alloc] initWithContentsOfURL:urlSound error:&playerError];
NSURL *urlNoSound = [[NSURL alloc]initWithString:[[NSBundle mainBundle]pathForResource:@"backSound" ofType:@"mp3"]];
playerNoSound = [[AVAudioPlayer alloc] initWithContentsOfURL:urlNoSound error:&playerError];playerSound.numberOfLoops = -1;
playerNoSound.numberOfLoops = -1;player = playerSound;
[player play];

下面解释一下AVAudioSession的一些设置参数

  • NSString *const AVAudioSessionCategoryAmbient;
    静音模式或者锁屏下不再播放音乐,和其他app声音混合。
  • NSString *const AVAudioSessionCategorySoloAmbient;
    默认模式,静音模式或者锁屏下不再播放音乐,不和其他app声音混合。
  • NSString *const AVAudioSessionCategoryPlayback;
    表示对于用户切换静音模式或者锁屏 都不理睬,继续播放音乐。并且不播放来自其他app的音乐
  • NSString *const AVAudioSessionCategoryRecord;
    不播放音乐,锁屏状态继续录音
  • NSString *const AVAudioSessionCategoryPlayAndRecord;
    播放音乐,并录音

Demo:https://download.csdn.net/download/baidu_37366055/13140917

iOS“伪后台“机制下如何保持APP一直运行在后台相关推荐

  1. Android判断App前台运行还是后台运行(运行状态)

    原文:http://p.codekk.com/detail/Android/wenmingvs/AndroidProcess AndroidProcess 项目地址:https://github.co ...

  2. android5.0以后获取应用运行状态,Android判断App前台运行还是后台运行(运行状态)...

    本文通过图文并茂的方式给大家介绍android判断app状态的相关内容,具体详情如下所示: 要了解这块,首先需要明白一些概念,app,process,task 1.process就是进程,是linux ...

  3. linux制作成后台服务,把dotnetcore 控制台app设置成linux后台服务

    1,新建service文件vim vim /etc/systemd/system/dotnetTest.serviceip 内容 [Unit] Description=dotnet consoleit ...

  4. 苹果iOS 7四种后台机制 优劣比较详细解析

    [iOS7后台机制详细解析]iOS系统作为市面上最受欢迎的移动操作系统,流畅的系统滑动和出色的操作体验是值得称道的.虽然iOS系统的后台伪多任务一直被Android用户所诟病,但从笔者看来iOS和An ...

  5. ios和android操作收拾,iOS和Android后台机制的比较

    发件人: 首先,让我们了解ios中所谓的"后台进程"是怎么回事吗? 让我尽可能的清楚: iOS多任务栏不包含"所有正在运行的应用程序的列表". 它包含" ...

  6. WP与IOS与Android的后台机制相同与不同

    简介: 1.Windows Phone与IOS的后台机制是 后台挂起 + 待机 + 通知代理 这样一种模式.也就是说一个程序在后台的时候,处于一种挂起状态,程序不能访问CPU.网络和其他系统资源,除了 ...

  7. iOS关于APP唤醒和在后台做的事

    相信很多人都遇到过这样的需求,就是想让APP保活.在手机系统日趋完善的阶段,安卓手机都很难实现保活了,更不用说以性能著称的苹果了,对吧. 众所周知,APP在压入后台以后会活一段时间,达到一定时间.或者 ...

  8. 苹果iOS13.2闷杀后台程序,你游戏APP或游戏有中招?PerfDog狗可以帮提前检测

    最近万众期待的苹果更新了iOS13.2系统,本以为带来超速体验,谁知道,微信聊着聊着,接个电话,微信挂了.哦呀发现其他app或者游戏切换后台,也出现同样情况,挂了.小弟君也是喜欢折腾的人,在iPhon ...

  9. iOS开发指南:从零基础到App Store上架(第2版 )

    第一部分 基础篇 第1章 开篇综述 2 1.1 iOS概述 2 1.1.1 iOS介绍 2 1.1.2 iOS 6新特性 2 1.2 开发环境及开发工具 3 1.3 本书中的约定 4 1.3.1 案例 ...

最新文章

  1. Linux启动流程(二)
  2. 机器学习 python_送书 | 深入浅出Python机器学习
  3. mysql提高缓存_合理配置MySQL缓存 提高缓存命中率
  4. 16 | 基础篇:怎么理解内存中的Buffer和Cache?
  5. 【Nutch基础教程之七】Nutch的2种运行模式:local及deploy
  6. 判断浏览器是否支持某个css属性
  7. 互斥锁和读写锁的区别
  8. 数百名车主因断网被锁车外 马斯克:将确保此类事件不再发生
  9. Dubbo项目简单实践
  10. python 重写抽象类编译错误_从零开始的Java之旅5.0继承、super、this、抽象类
  11. 鲁大师检测内存条_外观漂亮,做工精致,潜力巨大、十铨(Team)8GB×2 3200Mhz台式机内存条 火神系列 评测...
  12. python多线程图像识别_Python 多线程抓取图片效率对比
  13. 函数不可以直接调用其他函数内部定义的变量_基础知识回顾函数(一)
  14. mysql explain select_type
  15. ENVI入门系列教程---二、图像分析---9.遥感图像监督分类
  16. html在线快递单号打印,HTML 快递打印模板
  17. 华为小程序怎么弄出来_华为手机窗口小程序 华为窗口小程序怎么弄出来
  18. 手写Promise 封装Promise resolve reject then catch Promise.resolve Promise.reject
  19. 微信小助手:专为mac微信3.1.0发行!支持发朋友圈!支持僵尸粉清理
  20. opencv实现靶纸弹孔识别计数功能

热门文章

  1. 大数据信息资料采集:公众号武志红文章评论爬取八爪鱼采集器规则
  2. input text 默认值设置
  3. 中科院自动化研究所面试
  4. NLP基本功-文本相似度 | AI产品经理需要了解的AI技术通识
  5. Centos Development Tools 安装
  6. monthly rollup和security only的区别
  7. 电商APP源码功能解说
  8. 【智能合约】Go语言调用智能合约 | geth
  9. 在vue中二级页面返回一级页面
  10. 3D打印机喷头堵塞维修