iOS-如何保证app进入后台后,不被系统kill

写在前面:
为什么app进入后台后,会被系统kill掉?
答:当app进入后台,此时app所占用的内存就不是由我们自己控制,而是由系统去控制。当系统认为其他应用需要占用内存时,系统会优先吧进入后台的appKill掉,进而释放内存供其他应用使用。

当时需求方提出这个需求时。我也是一脸懵逼,他们需要在他们规定的时间范围内进行定位以及定位信息上传,当时我的第一个想法就是@”你这不是在监视别人吗?”。然并卵,只能默默的做。

在网上找了一下资料,在后台可以持续运行的app大多就是音乐播放器以及地图导航。目前常用的方式
A:当app进入后台时,持续进行定位操作,并且要告知系统,我当前仍然有操作未完成。
B:当app进入后台,循环播放无声音乐,无声音乐使用网上的资料方式进行操作就没有什么问题。
这里我主要说一下,持续定位操作

  • 开启后台服务。如下图

    iOS-如何保证app进入后台后,不被系统kill_第1张图片

    这里需要注意在Background Modes里面第一个选项,当你是用播放无声音乐的时候需要勾选。

  • 在info.list文件里面需要开启持续定位服务。

    source code 代码如下:

    <key>NSLocationAlwaysUsageDescriptionkey>
    <string>请允许使用定位功能string>
    <key>NSLocationWhenInUseUsageDescriptionkey>
    <string>请允许使用定位功能string>
    //以及
    <key>UIBackgroundModeskey>
    <array>
        <string>fetchstring>
        <string>locationstring>
    array>

完成上面两个步骤,剩下的就是代码了

  • 创建CLLocationManager对象,并且设置CLLocationManagerDelegate的代理
@property (nonatomic, strong) CLLocationManager *manager;

这里需要注意的是,需要加上系统判断,因为系统不一样持续定位的设置也是不一样的。

/**
 应用进入后台执行定位 保证进程不被系统kill
 */
-(void)rjxContinuedLocationManager
{
    //1.创建定位管理对象
    _manager = [[CLLocationManager alloc]init];

    //2.设置属性 distanceFilter、desiredAccuracy
    [_manager setDistanceFilter:kCLDistanceFilterNone];//实时更新定位位置
    [_manager setDesiredAccuracy:kCLLocationAccuracyBest];//定位精确度
    if([_manager respondsToSelector:@selector(requestAlwaysAuthorization)]){
        [_manager requestAlwaysAuthorization];
    }
    //该模式是抵抗程序在后台被杀,申明不能够被暂停
    _manager.pausesLocationUpdatesAutomatically = NO;

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
        //在后台也可定位
        [_manager requestAlwaysAuthorization];
    }
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
        _manager.allowsBackgroundLocationUpdates = YES;
    }
    //3.设置代理
    _manager.delegate = self;
    //4.开始定位
    [_manager startUpdatingLocation];
    //5.获取朝向
    [_manager startUpdatingHeading];
}
  1. 在didFinishLaunchingWithOptions方法里面调用rjxContinuedLocationManager这个方法。
// 当你的程序将要被挂起,会调用改方法
- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

    /** 应用进入后台执行定位 保证进程不被系统kill */

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self.manager startUpdatingLocation];
}

/** 应用进入后台执行定位 保证进程不被系统kill */
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    UIApplication *app = [UIApplication sharedApplication];
    __block  UIBackgroundTaskIdentifier bgTask;
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{

            if (bgTask != UIBackgroundTaskInvalid){
                bgTask = UIBackgroundTaskInvalid;
            }
        });
    }];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (bgTask != UIBackgroundTaskInvalid){
                bgTask = UIBackgroundTaskInvalid;
            }
        });
    });

    [self.manager startUpdatingLocation];

}

你可能感兴趣的:(iOS学习之路)