为啥即使应用程序状态是 UIApplicationStateBackground,backgroundTimeRemaining 也会给出 DBL_MAX?
Posted
技术标签:
【中文标题】为啥即使应用程序状态是 UIApplicationStateBackground,backgroundTimeRemaining 也会给出 DBL_MAX?【英文标题】:Why backgroundTimeRemaining gives DBL_MAX even if application state is UIApplicationStateBackground?为什么即使应用程序状态是 UIApplicationStateBackground,backgroundTimeRemaining 也会给出 DBL_MAX? 【发布时间】:2016-11-18 10:16:51 【问题描述】:每次我的应用程序从挂起模式唤醒时,我都会记录(写入文件)backgroundTimeRemaining 值,就在我开始使用过期处理程序的 UIApplication 后台任务之前,就像这样(在我发出网络请求的方法中):
if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
[Logger logIntoFileNamed:@"log" withContent:[NSString stringWithFormat:@" state %ld, background time remaining %.2f",(long)[[UIApplication sharedApplication] applicationState],[[UIApplication sharedApplication] backgroundTimeRemaining ]] andPrettyTime:true];
UIApplication* app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier task = [app beginBackgroundTaskWithExpirationHandler:^
[app endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
[Logger logIntoFileNamed:@"log" withContent:@" expiration handler executed " andPrettyTime:true];
];
根据文档,如果应用程序在前台,backgroundTimeRemaining
的值可能很大:
当应用在前台运行时,此属性中的值 保持适当的大。
但这里不是这样。我的方法被执行是因为应用程序状态等于UIApplicationStateBackground
。
我在这里错过了什么?
【问题讨论】:
刚刚检查过...当这种情况发生时,我实际上在Thread 1
上。哪个应该是主线程(当我从applicationDidEnterBackground:
运行这段代码时,它会显示Thread 5
)。问题是,我不是编写这部分代码的人,我想,因为我确信应用程序从挂起模式中被唤醒,所以我目前在后台线程上执行所有这些。 ..必须进行更多调查并查看代码,但如果我在主线程上,那么我会得到正常的结果,对吧?
【参考方案1】:
是的,根据文档:
如果 app 在 前景。
applicationDidEnterBackground
需要一些时间才能提供正确的backgroundTimeRemaining
。这应该从 180 左右开始。在带有dispatch_async
的异步线程中运行它并过滤掉前景值(>180)。
- (void)applicationDidEnterBackground:(UIApplication *)application
if([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)])
NSLog(@"Multitasking Supported");
__block UIBackgroundTaskIdentifier background_task;
background_task = [application beginBackgroundTaskWithExpirationHandler:^
//Clean up code. Tell the system that we are done.
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
];
//To make the code block asynchronous
dispatch_async(dispatch_get_main_queue(), ^
//### background task starts
NSLog(@"Running in the background\n");
while(TRUE)
//#### Filter Foreground Values
if ([[UIApplication sharedApplication] backgroundTimeRemaining] < 180)
NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]);
[NSThread sleepForTimeInterval:1]; //wait for 1 sec
//#### background task ends
//Clean up code. Tell the system that we are done.
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
);
else
NSLog(@"Multitasking Not Supported");
【讨论】:
您是否有记录此内容的链接(关于状态切换延迟)?我在执行任务时也使用了 dispatch_async,我只是离开了它,因为它是在另一个方法中调用的。无论如何,我进行了一些测试,如果我隔离代码并将其放在 applicationDidEnterBackground 内的一个空项目中:一切正常。问题是,这与我目前的设置不同。我在应用程序从挂起模式唤醒后运行此代码。在这种情况下,我得到 DBL_MAX 值。否则,它给出的值 【参考方案2】:这可能与您记录backgroundTimeRemaining
的方式有关。获得后台任务后尝试投入:
UIApplication *app = [UIApplication sharedApplication];
long appState = (long)app.applicationState;
if (appState == UIApplicationStateBackground)
__block UIBackgroundTaskIdentifier task = [app beginBackgroundTaskWithExpirationHandler:^
[app endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
[Logger logIntoFileNamed:@"log" withContent:@" expiration handler executed " andPrettyTime:true];
];
NSTimeInterval backgroundTimeRemaining = app.backgroundTimeRemaining;
[Logger logIntoFileNamed:@"log" withContent:[NSString stringWithFormat:@" state %ld, background time remaining %.2f", appState, backgroundTimeRemaining] andPrettyTime:true];
【讨论】:
以上是关于为啥即使应用程序状态是 UIApplicationStateBackground,backgroundTimeRemaining 也会给出 DBL_MAX?的主要内容,如果未能解决你的问题,请参考以下文章
iOS - 在设备设置中,如果我更改时间,即使在应用程序后台、已终止状态下也应该得到通知
即使状态没有改变,为啥 setState 会导致太多的重新渲染错误
为啥即使我没有将 vuex 状态绑定到任何 html 输入元素,我的 vuex 状态也会在更改组件级别状态时发生变化?
为啥 iPhone GPS 箭头出现在状态栏中,即使我没有在位置管理器上调用 startUpdatingLocation?
为啥即使在有状态小部件中使用 setstate 也无法获取更新的变量。因为我想在新的 TabBar 选项上更新我的 Container