一般情况下单例服务的可以存活保持允许的情况
- 与应用处于哪个活动界面无关,只要启动了就可以一直在后台存活
- 当从应用切到手机桌面或其他应用时也可以存活(没测试过内存不足以及长时间不切回来的情况)
- 服务器会在用户将应用销毁的情况下终止
只测试过以上几种情况,其他情况没有测试。
下面代码为一个在后台保持运行计时的单例服务,可以保证在app存活的时候一直运行:
class UploadTimeUtils {UploadTimeUtils._();static UploadTimeUtils _instance;/// 上传时间StateModel uploadTimeModel = StateModel.isEmpty();/// 是否上传成功modelEmptySuccessModel _uploadModel;/// 计时器Timer _timer;/// 是否在进行计时,true正在计时、false不在计时bool _timeState = false;/// 开始上传时间String _startTime = "";/// 结束上传时间String _stopTime = "";/// 缺省设备IdString _deviceId = "defaultDeviceId";/// 计时秒数int _count = 0;/// 时间单int _interval = 60;// 时间间隔为1svar period = const Duration(seconds: 1);// 获取单例对象static UploadTimeUtils getInstance() {if (_instance == null) {_instance = UploadTimeUtils._();_instance._startTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");_instance._stopTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");}return _instance;}/// 开始计时void startClock(String deviceId, int minute) {Log.e("定时分钟", "$minute");getInstance()._startTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");getInstance()._stopTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");// 标记开始计时getInstance()._timeState = true;// 重置开始倒计时getInstance()._count = 0;if (getInstance()._timer == null) {getInstance()._timer = Timer.periodic(period, (timer) {// 计秒getInstance()._count++;Log.e("计时器啊$_count", "$_count");// 每次到了时间间隔就上传运动数据,且在开始状态就上传数据if(getInstance()._count != 0 && (getInstance()._count % getInstance()._interval) == 0) {getInstance()._uploadTime(false);Log.e("定时1分钟上传数据", "$_count");}// 当时间大于计时的时间时停止计时if(getInstance()._count >= minute * 60) {getInstance()._timeState = false;if(getInstance()._timer !=null) {if(getInstance()._timer.isActive) {getInstance()._timer.cancel();}getInstance()._timer = null;Log.e("取消倒计时了", "达到时间取消的");}}});}}/// 停止计时void stopClock(bool isStop) {if(isStop) {if(getInstance()._timer !=null) {if(getInstance()._timer.isActive) {getInstance()._timer.cancel();}getInstance()._timer = null;}// 设置结束时间getInstance()._uploadTime(true);Log.e("取消倒计时了", "点击通知取消的");} else {Log.e("是开始", "不用执行特别多的操作");}}/// 设置结束上传时间/// [isStop] 是否是点击停止而进行的上传void _uploadTime(bool isStop)async {getInstance()._stopTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");if (getInstance()._timeState == true && getInstance()._startTime != getInstance()._stopTime) {Log.e("上传数据时的计时", "$_count");/// 设置结束上传时间var memberId = await SpUtils.getInt(SaveKey.memberId);String startTime = getInstance()._startTime;String stopTime = getInstance()._stopTime;Map<String, dynamic> params = {"deviceId": getInstance()._deviceId,"memberId": "$memberId","deviceType": "2","startSportTime": startTime,"endSportTime":stopTime};uploadTimeModel = await ApiService.post('API/deviceUpload/uploadData', params);if (StateEnum.isNotConnection != uploadTimeModel?.state && StateEnum.success == uploadTimeModel?.state) {_uploadModel = EmptySuccessModel.fromJson(uploadTimeModel.data);if (_uploadModel?.code == 0) {Log.e("数据上传成功", '数据上传状态:${_uploadModel?.msg}');} else {Log.e("数据上传失败", '数据上传状态:${_uploadModel?.msg}');}}if (isStop) {getInstance()._timeState = false;}} else {if(isStop) {getInstance()._timeState = false;}}/// 重置上传开始上传时间getInstance()._startTime = getInstance()._stopTime;}}
