一般情况下单例服务的可以存活保持允许的情况
- 与应用处于哪个活动界面无关,只要启动了就可以一直在后台存活
- 当从应用切到手机桌面或其他应用时也可以存活(没测试过内存不足以及长时间不切回来的情况)
- 服务器会在用户将应用销毁的情况下终止
只测试过以上几种情况,其他情况没有测试。
下面代码为一个在后台保持运行计时的单例服务,可以保证在app存活的时候一直运行:
class UploadTimeUtils {
UploadTimeUtils._();
static UploadTimeUtils _instance;
/// 上传时间
StateModel uploadTimeModel = StateModel.isEmpty();
/// 是否上传成功model
EmptySuccessModel _uploadModel;
/// 计时器
Timer _timer;
/// 是否在进行计时,true正在计时、false不在计时
bool _timeState = false;
/// 开始上传时间
String _startTime = "";
/// 结束上传时间
String _stopTime = "";
/// 缺省设备Id
String _deviceId = "defaultDeviceId";
/// 计时秒数
int _count = 0;
/// 时间单
int _interval = 60;
// 时间间隔为1s
var 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;
}
}