91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決iOS應用進入后臺后計時器和位置更新停止問題

發布時間:2021-07-21 09:49:04 來源:億速云 閱讀:375 作者:小新 欄目:移動開發

這篇文章主要介紹如何解決iOS應用進入后臺后計時器和位置更新停止問題,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

由于iOS系統為“偽后臺”運行模式,當按下HOME鍵時,如程序不做任何操作,應用會有5秒的執行緩沖時間,隨機程序被掛起,所有任務終端,包括計時器和位置更新等操作,但程序打開后臺模式開關后,部分任務可以再后臺執行,如音頻,定位,藍牙,下載,VOIP,即便如此,程序的后臺運行最多可以延長594秒(大概是10分鐘)。不幸的是,程序在聲明后臺模式后很有可能在app上架時被拒。基于此,我研究出了不用申明后臺模式就能讓計時器和定位在app進入前臺時繼續運行的方法。

  實現原理如下:

  利用iOS的通知機制,在程序進入后臺和再次回到前臺時發送通知,并記錄進入后臺的當前時間和再次回到前臺的當前時間,算出兩者的時間間隔,在程序任何需要的地方添加通知監聽者,在監聽方法中執行代碼塊,代碼塊內參數為通知對象和計算出的時間間隔。以計時器為例,程序再進入后臺后,計時器停止運行,此時運用上述方法,在程序再次回到前臺時執行代碼塊中內容,將程序進入后臺時計時器的當前時間間隔加上代碼塊的時間間隔參數就能使計時器準確無誤地計時。廢話不多說,上代碼:

在AppDelegate.m實現文件中:

- (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.
  [[NSNotificationCenter defaultCenter]postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
  // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
  [[NSNotificationCenter defaultCenter]postNotificationName:UIApplicationWillEnterForegroundNotification object:nil];
}

代碼說明:程序進入后臺后,利用系統通知機制通知程序進入后臺和再次回到前臺,監聽對象為所有對象。

之后定義一個處理程序進入后臺的類YTHandlerEnterBackground

//
// YTHandlerEnterBackground.h
// 分時租賃
//
// Created by 柯其譜 on 17/2/24.
// Copyright © 2017年 柯其譜. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
/** 進入后臺block typedef */
typedef void(^YTHandlerEnterBackgroundBlock)(NSNotification * _Nonnull note, NSTimeInterval stayBackgroundTime);
/** 處理進入后臺并計算留在后臺時間間隔類 */
@interface YTHandlerEnterBackground : NSObject
/** 添加觀察者并處理后臺 */
+ (void)addObserverUsingBlock:(nullable YTHandlerEnterBackgroundBlock)block;
/** 移除后臺觀察者 */
+ (void)removeNotificationObserver:(nullable id)observer;
@end

在YTHandlerEnterBackground.m實現文件中:

//
// YTHandlerEnterBackground.m
// 分時租賃
//
// Created by 柯其譜 on 17/2/24.
// Copyright &copy; 2017年 柯其譜. All rights reserved.
//
#import "YTHandlerEnterBackground.h"
@implementation YTHandlerEnterBackground
+ (void)addObserverUsingBlock:(YTHandlerEnterBackgroundBlock)block {
  __block CFAbsoluteTime enterBackgroundTime;
  [[NSNotificationCenter defaultCenter]addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
    if (![note.object isKindOfClass:[UIApplication class]]) {
      enterBackgroundTime = CFAbsoluteTimeGetCurrent();
    }
  }];
  __block CFAbsoluteTime enterForegroundTime;
  [[NSNotificationCenter defaultCenter]addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
    if (![note.object isKindOfClass:[UIApplication class]]) {
      enterForegroundTime = CFAbsoluteTimeGetCurrent();
      CFAbsoluteTime timeInterval = enterForegroundTime-enterBackgroundTime;
      block? block(note, timeInterval): nil;
    }
  }];
}
+ (void)removeNotificationObserver:(id)observer {
  if (!observer) {
    return;
  }
  [[NSNotificationCenter defaultCenter]removeObserver:observer name:UIApplicationDidEnterBackgroundNotification object:nil];
  [[NSNotificationCenter defaultCenter]removeObserver:observer name:UIApplicationWillEnterForegroundNotification object:nil];
}
@end

該類實現了用來添加通知監聽者并處理后臺和移除通知監聽者的方法,需要注意的是,在addObserverUsingBlock方法中,必須有if (![note.object isKindOfClass:[UIApplication class]])的判斷,否則addObserverForName方法中的代碼塊會執行多次,此代碼執行了兩次。addObserverUsingBlock方法是在viewWillAppear方法中調用添加通知監聽者,在viewWillDisappear方法中調用移除通知監聽者。

例如,在使用了計時器NSTimer控制器中:

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  [YTHandlerEnterBackground addObserverUsingBlock:^(NSNotification * _Nonnull note, NSTimeInterval stayBackgroundTime) {
    self.rentTimerInterval = self.rentTimerInterval-stayBackgroundTime;
  }];
}
- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  [self.timer invalidate];
  [YTHandlerEnterBackground removeNotificationObserver:self];
}

我定義了一個倒計時5分鐘的計時器對象timer屬性,并定義了一個計時器當前倒計時時間間隔rentTimerInterval屬性,在添加通知監聽者代碼塊中,rentTimerInterval等于進入后臺時的倒計時時間間隔減去程序停留在后臺的時間間隔,當計時器再次回到前臺時,計時器此時的時間間隔是持續的。雖然計時器并未在后臺持續運行,但是使用了此方法,同樣實現了計時器的正確即時。

同樣的,當程序存在位置更新功能時,當程序進入后臺,位置服務對象會自動停止更新,此時的作法依然是調用上述兩個處理進入后臺的方法,使得程序進入后臺后,再次開始定位:

在需要位置更新的類中:

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  self.locService.delegate = self;
  [self.locService startUserLocationService];
  //進入后臺再進入前臺重新開始定位
  [YTHandlerEnterBackground addObserverUsingBlock:^(NSNotification * _Nonnull note, NSTimeInterval stayBackgroundTime) {
    [self.locService startUserLocationService];
  }];
}
- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  //停止定位
  self.locService.delegate = nil;
  [self.locService stopUserLocationService];
  //移除后臺監聽
  [YTHandlerEnterBackground removeNotificationObserver:self];
}

此處使用的是百度地圖SDK

利用這種方法,像是計時器和位置更新等需要在后臺運行的任務都可以實現相應的需求,只是麻煩的是,在任何需要的類中都要調用這兩種方法,你可以根據自己的需求,在程序進入后臺和再次回到前臺時添加別的參數(通知對象參數是必須的),例如保存進入后臺前的操作等等。或是定義不同的添加通知監聽者的方法以實現不同的需求。

以上是“如何解決iOS應用進入后臺后計時器和位置更新停止問題”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

ios
AI

临潭县| 彭泽县| 陇南市| 邛崃市| 寿阳县| 泰顺县| 深泽县| 通河县| 交城县| 和硕县| 西林县| 南丰县| 专栏| 郓城县| 柘荣县| 望都县| 忻城县| 应用必备| 南阳市| 西青区| 青浦区| 札达县| 高台县| 唐海县| 阿鲁科尔沁旗| 佛学| 四子王旗| 盱眙县| 五常市| 招远市| 临高县| 城步| 凤台县| 海淀区| 沙雅县| 金堂县| 藁城市| 偏关县| 聂拉木县| 拜泉县| 正安县|