先介紹一篇關(guān)于后臺(tái)運(yùn)行的文章:http://www.itdecent.cn/p/174fd2673897
此篇文章的博主已經(jīng)非常詳細(xì)的介紹了IOS后臺(tái)運(yùn)行的一些方法,其中播放無聲音樂、后臺(tái)通知,這些我基本都有試過。當(dāng)時(shí)做的項(xiàng)目是一個(gè)計(jì)步類的項(xiàng)目,因?yàn)橄到y(tǒng)計(jì)步器不能實(shí)時(shí)顯示步數(shù)變化,用戶體驗(yàn)有點(diǎn)差,后來選用加速計(jì)計(jì)步,這樣就需要長(zhǎng)久的后臺(tái)運(yùn)行來保證數(shù)據(jù)完整性。
后來跟博主一樣選擇了定位來保持后臺(tái)運(yùn)行,博主已經(jīng)將方法講的差不多了;我在使用過程中發(fā)現(xiàn)了一些可以保證APP后臺(tái)穩(wěn)定運(yùn)行的細(xì)節(jié),為博主補(bǔ)充下,也方便大家借鑒,有寫的不對(duì)的還請(qǐng)大家指正。
關(guān)于定位服務(wù):
1.info.plist里邊需要加入后臺(tái)運(yùn)行的種類:Required background modes(Array類型) --> App registers for location updates(string類型),這個(gè)大家基本都知道。或者直接在Capabilities里邊將Background Modes 打開并勾選Location updates即可。IOS8以上好像需要加入Privacy - Location Always Usage Description 類型String,是彈出定位提示的文字,如果沒有這個(gè)好像是不彈提示的,具體忘了,大家可以嘗試下。

2.AppDelegate.m? 導(dǎo)入 #import <CoreLocation/CoreLocation.h> //GPS
在方法 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 中創(chuàng)建gps:
locationMannager = [[CLLocationManager alloc] init];
locationMannager.delegate = self;
locationMannager.activityType = CLActivityTypeFitness;
locationMannager.distanceFilter = kCLLocationAccuracyThreeKilometers;
locationMannager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locationMannager.allowsBackgroundLocationUpdates = YES; //允許后臺(tái)刷新
locationMannager.pausesLocationUpdatesAutomatically = NO;//允許自動(dòng)暫停定位服務(wù)
//該模式是抵抗ios在后臺(tái)殺死程序設(shè)置,iOS會(huì)根據(jù)當(dāng)前手機(jī)使用狀況會(huì)自動(dòng)關(guān)閉某些應(yīng)用程序的后臺(tái)刷新,該語句申明不能夠被暫停,但是不一定iOS系統(tǒng)在性能不佳的情況下強(qiáng)制結(jié)束應(yīng)用刷新
if (IS_IOS_8) {
????????? [locationMannager requestAlwaysAuthorization];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
?????????? [locationMannager startUpdatingLocation];
????????? [NSThread sleepForTimeInterval:5];
??????????? [locationMannager stopUpdatingLocation];
??????????? if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) {
??????????? //第一次打開時(shí)系統(tǒng)還沒允許使用定位,直接關(guān)閉會(huì)導(dǎo)致后臺(tái)駐留失敗,所以定位還未打開時(shí)不主動(dòng)關(guān)閉,并不會(huì)增加太多耗電量。
??????????? [locationMannager stopUpdatingLocation];
???????????? }
});
3.AppDelegate.m 在進(jìn)入后臺(tái)的代理方法中實(shí)現(xiàn)后臺(tái)運(yùn)行的方法:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
????????? inBackground = YES;
????????? UIBackgroundTaskIdentifier __block bgTask;
????????? bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
???????? ? ? ? ? ? ? [application endBackgroundTask:bgTask];
???????????????????? bgTask = UIBackgroundTaskInvalid;
????????? }];
???????? dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY
???????? _DEFAULT, 0), ^{
????????????????? int i = 0;
????????????????? int j = 0;
????????????????? while (inBackground) {
???????????????????????????? i = 0;
???????????????????????????? [locationMannager startUpdatingLocation];
???????????????????????????? while (i < 150 && inBackground) {
???????????????????????????????????????? NSLog(@"時(shí)間:%d 總時(shí)間:%d?
???????????????????????????????????????? %.2f",i,j,application.backgroundTimeRemaining);
???????????????????????????????????????? i++;
???????????????????????????????????????? j++;
???????????????????????????????????????? [NSThread sleepForTimeInterval:1];
?????????????????????????????? }
???????????????????? }
??????????????????? [application endBackgroundTask:bgTask];
?????????????????? bgTask = UIBackgroundTaskInvalid;
?????????? });
}
這一部分粗體文字非常重要,這個(gè)是后臺(tái)定位穩(wěn)定運(yùn)行的必要設(shè)定。
[NSThread sleepForTimeInterval:5];雖然沒明白為什么必須加,但是加了這個(gè)之后會(huì)解決引用文博主出現(xiàn)的有時(shí)不能持續(xù)運(yùn)行的問題。經(jīng)過我多次測(cè)試出現(xiàn)引用文博主那種情況一般是這樣的:如果APP打開后定位圖標(biāo)還亮著,home鍵進(jìn)入后臺(tái),后臺(tái)可運(yùn)行時(shí)間backgroundTimeRemaining會(huì)被刷新,可達(dá)到穩(wěn)定允許的效果;如果是在APP打開后大約30秒之后定位圖標(biāo)消失了,再進(jìn)入后臺(tái),backgroundTimeRemaining將不會(huì)被刷新,后臺(tái)運(yùn)行中斷。
但是如果加了[NSThread sleepForTimeInterval:5];將不會(huì)出現(xiàn)這種情況,不管圖標(biāo)有沒有消失都能刷新backgroundTimeRemaining,backgroundTimeRemaining將變?yōu)闊o限大。可以看到,后臺(tái)運(yùn)行的時(shí)候會(huì)在每150秒的時(shí)候激活一次定位,即便一開始background Time Remaining是180秒,150秒的時(shí)候激活定位,background Time Remaining會(huì)被刷新,變?yōu)闊o限大。
因?yàn)槎ㄎ辉O(shè)置的精度是千米級(jí),150秒激活一次,雖然是處于持續(xù)定位,但是耗電量不是很大,后邊有測(cè)試截圖。
我給項(xiàng)目加了widget,可以實(shí)時(shí)觀察后臺(tái)運(yùn)行情況,附上我測(cè)試的圖。
閑來無事把代碼重新碼了一遍,發(fā)現(xiàn)還好使,有需要的自取吧。
鏈接: https://pan.baidu.com/s/1CMlzbNjwg7f2whvzvNTvSQ? 密碼: wdrw