iOS 13杀后台问题排查
author:
dinglei Create by 20191219
已知条件仅为:最右在iOS 13系统上会杀后台。具体表现为,打开最右app,挂后台,过一会再打开最右,就变成冷启动app了。
-
[iOS13后台通知适配](#iOS13 后台通知适配)
[iOS13新功能BackgroundTasks](#iOS13 新功能BackgroundTasks)
一. 获取日志,解析信息
日志来源:bugly的统计,用户手机的ips日志
1. bugly日志都是记录的crash信息和一些自报的error信息,并未获取到任何关于“杀后台”的信息。【发现一个特殊的bug,iOS 13特有的,后续需要特殊查一下】
2. 联系了被杀后台的用户,收集ips日志信息-->解析日志地址-->通过dysm解析日志:
结论:通过日志分析拿不到任何关于杀后台的信息,也就说杀后台之后,系统未留下任何信息
二. 性能检测
切入点:通过perfDog工具检测app的CPU使用情况和内存占用情况
结论:app挂后台之后,CPU立刻就下降了,Memory的使用也趋于稳定,并未出现再度波动的情况,一切正常
三. 后台任务使用review
切入点:查找使用
UIBackgroundTaskIdentifier
的地方
1. UIBackgroundTaskIdentifier
的用法
UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
[self deleteOldFilesWithCompletionBlock:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
2. UIBackgroundTaskIdentifier
使用的地方很多
3. github上的一个开源库firebase-ios-sdk,有解决过相关bug
修改的方向是调整后台任务的使用方式
3. 最右app临时删除所有UIBackgroundTaskIdentifier
后打包测试,发现杀后台的现象有所减缓,但是并未全部消除。
结论:app中有很多地方使用了beginBackgroundTaskWithExpirationHandler,但是该方法的使用需要严格控制endBackgroundTask的成对出现。因此最右app可能会因为后台任务的滥用导致系统杀死app,这也是为什么修复这个这个问题可以减缓杀后台的现象。
四. iOS13 后台通知适配
切入点:iOS 13 app的生命周期发生变化,引入了SceneDelegate
系统的一些行为通知发生了变化,需要特殊适配:
if (@available(iOS 13.0, *)) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appWillResignActive:)
name:UISceneWillDeactivateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appDidBecomeActive:)
name:UISceneDidActivateNotification object:nil];
}
else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appWillResignActive:)
name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(appDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
因此,我又对这一堆通知做了适配,重新打包,测试之后发现对“杀后台“没有优化效果。
结论:系统行为的通知需要在后续开发中适配,但是该问题并不是引起"杀后台"的原因。
五. iOS13 新功能BackgroundTasks
切入点:iOS 13引入了一个新的概念:BackgroundTasks
iOS 13提供了一个新的功能,叫BackgroundTasks,该任务提供两种方式:BGProcessingTaskRequest和BGAppRefreshTaskRequest,在didFinishLaunchingWithOptions之后注册了后台任务,当系统调用后台任务的时候,app可以做相应的事情。至于系统何时何地调用,文档没有说明,咱也就不知道了。
最右app里面加入这个功能后,打包,测试,然并卵!
结论:新功能BackgroundTasks对”杀后台“毫无影响。
六. 移除所有前后台监听行为
事情进展到现在,能研究的方向都研究了,依旧毫无进展,并且还无头的苍蝇,找不到切入点。那就只能回归事情的本质,既然是前后台会杀,那么就直接把关于前后台的代码干掉。
删除UIApplicationDidBecomeActiveNotification、UIApplicationWillResignActiveNotification、UIApplicationWillEnterForegroundNotification、UIApplicationDidEnterBackgroundNotification等通知。
删除这么通知后,打包,测试,然并卵!
结论:前后台通知行为对”杀后台“毫无影响。
七. 关闭所有网络
切入点:在跟用户联系的过程中有这么一个操作场景:用户打开app,在首页tab往下滚动一段,然后不做任何操作,挂后台,依旧会”杀后台“。这时候app做的事情其实很少:初始化+获取默认配置+加载闪屏+首页UI+首页获取数据+socket启动等。
经过分析,在仅仅打开首页的情况也会”杀后台“,UI的操作不会导致这个问题,因为UI都是在主线程,一旦有问题的话,app活着的时候就因为出问题,所以疑点怀疑到异步获取数据上。
在加载一次数据后【保证首页有点数据,别空白了】,关闭所有网络请求,之后进入app,挂后台,依旧会”杀后台“。
结论:异步的网络行为和数据处理行为对”杀后台“毫无影响。
八. 版本追踪
切入点:前面所有的方法都未找到原因,只能静心重新寻找方向,继续看日志,看反馈,发现最早的反馈大概是5.1.6。这个版本前后辩护比较大,5.1.6其实是一个补丁版本,所以要回溯到5.1.5,但是5.1.5当时换了新版的Xcode 11,所以咱们现在做版本追踪就得考虑两个方向:app版本和Xcode版本。
为了检测是否是Xcode版本导致,所以回溯到5.1.3,使用Xcode 10 和 Xcode 11打包5.1.3版本,发现都不”杀后台“。
结论:Xcode版本对”杀后台“毫无影响。
接下来就是检测app版本了,我们安装了5.1.3、5.1.5、5.1.8,发现5.1.8开始杀后台。
为啥没有5.1.6、5.1.7。因为5.1.6版本是补丁版本,5.1.7是加发版本,查看发版记录,发现5.1.6更换了广告SDK+修复了几个crash问题,5.1.7是增加了flutter功能。
既然这样,那这两个版本都非常可疑,那就重新打包、测试。
发现5.1.6就开始出现”杀后台“,下面是5.1.6的版本变动记录:
由于此次修改记录有两个SDK变动,所以先从第一次变动拉分支出来验证:
打包,测试,发现会杀后台。结论:这次变动是罪魁祸首。
为了再一次验证是头条SDK的问题,从最新分支拉代码,然后单独删除头条的SDK
打包,测试,不会杀后台。
结论:”杀后台“确定是由头条广告SDK引起的。
至此,已经锁定了最右”杀后台“的原因,由于SDK是黑盒,我们没法查看代码,所以遗憾的是不知道SDK里面到底是哪行代码有问题。但是经过这几天的排查,也得到了一些经验:
产生原因:
”杀后台“确实跟iOS 13系统有关系。猜测是系统对某些资源的使用控制更加严格了。
”杀后台“跟手机状态有关系,比如:手机在低电量、充电、或者存储空间不足的时候很容易出现”杀后台“。
app开发的时候,资源使用不当、API使用不当、版本未适配好等都是最大的原因。
需要处理的点:
UIBackgroundTaskIdentifier使用不当会产生background kill
iOS 13的生命周期发生变化,需要做适配
在跟头条SDK的同学深聊后,确定了“杀后台”确实是由SDK引入的,并且原因是由于后台任务管理不当引起的,这也印证了上述说的UIBackgroundTaskIdentifier使用不当会引起“杀后台”.