iOS"偽后臺(tái)"機(jī)制下如何保持APP一直運(yùn)行在后臺(tái)【轉(zhuǎn)】

最近在做番茄鐘的功能种呐。首先簡(jiǎn)單介紹一下番茄鐘吧形入,就是25分鐘工作番茄工作法乞榨。先說(shuō)一下** 番茄工作法 **:

番茄工作法是簡(jiǎn)單易行的時(shí)間管理方法熔酷,是由弗朗西斯科·西里洛于1992年創(chuàng)立的一種相對(duì)于GTD更微觀的時(shí)間管理方法孤紧。

使用番茄工作法,選擇一個(gè)待完成的任務(wù)拒秘,將番茄時(shí)間設(shè)為25分鐘号显,專注工作,中途不允許做任何與該任務(wù)無(wú)關(guān)的事躺酒,直到番茄時(shí)鐘響起押蚤,然后在紙上畫一個(gè)X短暫休息一下(5分鐘就行),每4個(gè)番茄時(shí)段多休息一會(huì)兒羹应。

番茄工作法極大地提高了工作的效率揽碘,還會(huì)有意想不到的成就感。

那么功能就相當(dāng)于一個(gè)25分鐘的鬧鐘,可以播放背景音樂雳刺,到點(diǎn)給用戶提醒劫灶。

功能聽起來(lái)很簡(jiǎn)單是不是?其實(shí)挺多坑的掖桦。

開發(fā)過程中遇到了2個(gè)問題本昏。

因?yàn)榉宴娛?5分鐘,那么當(dāng)用戶開啟番茄鐘后很可能在中途就將APP切換到了后臺(tái)枪汪,那么幾分鐘程序就會(huì)被系統(tǒng)kill掉涌穆。

當(dāng)用戶開啟番茄鐘的背景音樂時(shí),APP切換到后臺(tái)或者鎖屏狀態(tài)時(shí)雀久,音樂都會(huì)立即停止播放宿稀。

OK,下面我們一步一步來(lái)分析并解決這兩個(gè)問題赖捌。

** 首先要理解iOS系統(tǒng)的后臺(tái)機(jī)制 **

我們都知道祝沸,蘋果對(duì)APP占用硬件資源管的很嚴(yán),更不要說(shuō)應(yīng)用后臺(tái)時(shí)候的資源占用了巡蘸。正常情況下,使用應(yīng)用時(shí)擂送,APP從硬盤加載到內(nèi)存悦荒,開始工作;當(dāng)用戶按下home鍵嘹吨,APP便被掛起搬味,依然駐留在內(nèi)存中,這種狀態(tài)下蟀拷,不調(diào)用蘋果已開放的幾種后臺(tái)方法碰纬,程序便不會(huì)運(yùn)行;如果在這個(gè)時(shí)候问芬,使程序繼續(xù)運(yùn)行悦析,則為后臺(tái)狀態(tài);如果當(dāng)前內(nèi)存將要不夠用時(shí)此衅,系統(tǒng)會(huì)自動(dòng)把之前掛起狀態(tài)下的APP請(qǐng)出內(nèi)存强戴。所以我們看到,有些時(shí)候打開APP時(shí)挡鞍,還是上次退出時(shí)的那個(gè)頁(yè)面那些數(shù)據(jù)骑歹,有時(shí)則是重新從閃屏進(jìn)入。

iOS系統(tǒng)后臺(tái)機(jī)制大概可以分為5種狀態(tài)

Not Running:APP沒有啟動(dòng)墨微,也沒有后臺(tái)運(yùn)行道媚。

Active:用戶正在使用APP,比如說(shuō)我們聊微信看網(wǎng)頁(yè)的時(shí)候,APP就處于Active狀態(tài)最域。

Inactive:這是一個(gè)過渡的狀態(tài)谴分,APP雖然打開了,但是用戶沒有跟APP有任何互動(dòng)操作羡宙。

Background:APP在后臺(tái)運(yùn)行狸剃,微信會(huì)在沒有打開的時(shí)候接收消息。

Suspended:APP雖然在后臺(tái)運(yùn)行狗热,但是處于休眠狀態(tài)钞馁,只占用一點(diǎn)內(nèi)存。

** 那么我需要的是Background模式匿刮。即APP在后臺(tái)運(yùn)行同時(shí)保持程序active的狀態(tài) **

首先去xCode里面設(shè)置僧凰。到info.plist中添加以下信息:

image

然后到Capabilities里面打開后臺(tái)模式,并根據(jù)項(xiàng)目的要求勾選對(duì)應(yīng)的功能熟丸。我這里只需要保持后臺(tái)運(yùn)行并且播放背景音樂及通知功能训措。所以就勾選了第一個(gè)和最后一個(gè)

image

以上這兩步是告訴系統(tǒng)我這個(gè)APP支持后臺(tái)模式,對(duì)應(yīng)的環(huán)境為音頻環(huán)境光羞。

可是到這一步绩鸣,APP還是不能長(zhǎng)時(shí)間運(yùn)行到后臺(tái)。

為什么纱兑?我們思考一下呀闻。我們讓程序支持了后臺(tái)運(yùn)行的模式。那么我們是不是還需要系統(tǒng)知道我們的程序要在后臺(tái)運(yùn)行多久呢潜慎?我們需要告訴系統(tǒng)我們期望APP在后臺(tái)存活的時(shí)間捡多。

首先聲明一個(gè)屬性

@property(nonatomic,assign)UIBackgroundTaskIdentifier bgTask;

在進(jìn)入后臺(tái)的時(shí)候通過AppDelegate里面的方法:

-(void)applicationDidEnterBackground:(UIApplication*)application{[selfcomeToBackgroundMode];}-(void)comeToBackgroundMode{//初始化一個(gè)后臺(tái)任務(wù)BackgroundTask,這個(gè)后臺(tái)任務(wù)的作用就是告訴系統(tǒng)當(dāng)前app在后臺(tái)有任務(wù)處理铐炫,需要時(shí)間UIApplication*app=[UIApplication sharedApplication];self.bgTask=[app beginBackgroundTaskWithExpirationHandler:^{[app endBackgroundTask:self.bgTask];self.bgTask=UIBackgroundTaskInvalid;}];//開啟定時(shí)器 不斷向系統(tǒng)請(qǐng)求后臺(tái)任務(wù)執(zhí)行的時(shí)間self.timer=[NSTimer scheduledTimerWithTimeInterval:25.0target:selfselector:@selector(applyForMoreTime)userInfo:nil repeats:YES];[self.timer fire];}-(void)applyForMoreTime{//如果系統(tǒng)給的剩余時(shí)間小于60秒 就終止當(dāng)前的后臺(tái)任務(wù)垒手,再重新初始化一個(gè)后臺(tái)任務(wù),重新讓系統(tǒng)分配時(shí)間倒信,這樣一直循環(huán)下去科贬,保持APP在后臺(tái)一直處于active狀態(tài)。if([UIApplication sharedApplication].backgroundTimeRemaining<60){[[UIApplication sharedApplication]endBackgroundTask:self.bgTask];self.bgTask=[[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{[[UIApplication sharedApplication]endBackgroundTask:self.bgTask];self.bgTask=UIBackgroundTaskInvalid;}];}}

現(xiàn)在就可以讓我們的APP一直運(yùn)行在后臺(tái)啦鳖悠!總結(jié)下來(lái)的思路就是:通過一個(gè)后臺(tái)任務(wù)(這個(gè)任務(wù)我們也不用管唆迁,它存在的意義就是和系統(tǒng)去請(qǐng)求后臺(tái)運(yùn)行的一定的時(shí)間),這個(gè)時(shí)間我們不知道也不用去管竞穷,我們可以通過該時(shí)間還剩下多少判斷是否繼續(xù)請(qǐng)求時(shí)間唐责,如此循環(huán),我們就可以不斷的請(qǐng)求時(shí)間來(lái)保持我們的app一直運(yùn)行在后臺(tái)瘾带。

接下來(lái)解決音樂在后臺(tái)模式(切換到后臺(tái)或者鎖屏狀態(tài))下停止播放的問題鼠哥。

其實(shí)很簡(jiǎn)單。

//設(shè)置后臺(tái)模式和鎖屏模式下依然能夠播放[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];[[AVAudioSession sharedInstance]setActive:YES error:nil];//初始化播放器和兩個(gè)音頻(一個(gè)有聲 一個(gè)無(wú)聲)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的一些設(shè)置參數(shù)

NSString *const AVAudioSessionCategoryAmbient;

靜音模式或者鎖屏下不再播放音樂,和其他app聲音混合朴恳。

NSString *const AVAudioSessionCategorySoloAmbient;

默認(rèn)模式抄罕,靜音模式或者鎖屏下不再播放音樂,不和其他app聲音混合于颖。

NSString *const AVAudioSessionCategoryPlayback;

表示對(duì)于用戶切換靜音模式或者鎖屏 都不理睬呆贿,繼續(xù)播放音樂。并且不播放來(lái)自其他app的音樂

NSString *const AVAudioSessionCategoryRecord;

不播放音樂森渐,鎖屏狀態(tài)繼續(xù)錄音

NSString *const AVAudioSessionCategoryPlayAndRecord;

播放音樂做入,并錄音

Demo地址:https://github.com/BoYangZuo/KeepAppActive

作者:flightlessBirdT

鏈接:http://www.reibang.com/p/d62c6d3ae8ff

來(lái)源:簡(jiǎn)書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)同衣,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處竟块。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耐齐,隨后出現(xiàn)的幾起案子浪秘,更是在濱河造成了極大的恐慌,老刑警劉巖埠况,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耸携,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡辕翰,警方通過查閱死者的電腦和手機(jī)夺衍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)金蜀,“玉大人刷后,你說(shuō)我怎么就攤上這事的畴≡ǔ” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵丧裁,是天一觀的道長(zhǎng)护桦。 經(jīng)常有香客問我,道長(zhǎng)煎娇,這世上最難降的妖魔是什么二庵? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮缓呛,結(jié)果婚禮上催享,老公的妹妹穿的比我還像新娘。我一直安慰自己哟绊,他們只是感情好因妙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般攀涵。 火紅的嫁衣襯著肌膚如雪铣耘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天以故,我揣著相機(jī)與錄音蜗细,去河邊找鬼。 笑死怒详,一個(gè)胖子當(dāng)著我的面吹牛炉媒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棘利,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼橱野,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了善玫?” 一聲冷哼從身側(cè)響起水援,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茅郎,沒想到半個(gè)月后蜗元,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡系冗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年奕扣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掌敬。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惯豆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奔害,到底是詐尸還是另有隱情楷兽,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布华临,位于F島的核電站芯杀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏雅潭。R本人自食惡果不足惜揭厚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扶供。 院中可真熱鬧筛圆,春花似錦、人聲如沸椿浓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至粉寞,卻和暖如春尼荆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唧垦。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工捅儒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人振亮。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓巧还,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親坊秸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子麸祷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容