一般情况下单例服务的可以存活保持允许的情况

    1. 与应用处于哪个活动界面无关,只要启动了就可以一直在后台存活
    2. 当从应用切到手机桌面或其他应用时也可以存活(没测试过内存不足以及长时间不切回来的情况)
    3. 服务器会在用户将应用销毁的情况下终止

    只测试过以上几种情况,其他情况没有测试。

    下面代码为一个在后台保持运行计时的单例服务,可以保证在app存活的时候一直运行:

    1. class UploadTimeUtils {
    2. UploadTimeUtils._();
    3. static UploadTimeUtils _instance;
    4. /// 上传时间
    5. StateModel uploadTimeModel = StateModel.isEmpty();
    6. /// 是否上传成功model
    7. EmptySuccessModel _uploadModel;
    8. /// 计时器
    9. Timer _timer;
    10. /// 是否在进行计时,true正在计时、false不在计时
    11. bool _timeState = false;
    12. /// 开始上传时间
    13. String _startTime = "";
    14. /// 结束上传时间
    15. String _stopTime = "";
    16. /// 缺省设备Id
    17. String _deviceId = "defaultDeviceId";
    18. /// 计时秒数
    19. int _count = 0;
    20. /// 时间单
    21. int _interval = 60;
    22. // 时间间隔为1s
    23. var period = const Duration(seconds: 1);
    24. // 获取单例对象
    25. static UploadTimeUtils getInstance() {
    26. if (_instance == null) {
    27. _instance = UploadTimeUtils._();
    28. _instance._startTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");
    29. _instance._stopTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");
    30. }
    31. return _instance;
    32. }
    33. /// 开始计时
    34. void startClock(String deviceId, int minute) {
    35. Log.e("定时分钟", "$minute");
    36. getInstance()._startTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");
    37. getInstance()._stopTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");
    38. // 标记开始计时
    39. getInstance()._timeState = true;
    40. // 重置开始倒计时
    41. getInstance()._count = 0;
    42. if (getInstance()._timer == null) {
    43. getInstance()._timer = Timer.periodic(period, (timer) {
    44. // 计秒
    45. getInstance()._count++;
    46. Log.e("计时器啊$_count", "$_count");
    47. // 每次到了时间间隔就上传运动数据,且在开始状态就上传数据
    48. if(getInstance()._count != 0 && (getInstance()._count % getInstance()._interval) == 0) {
    49. getInstance()._uploadTime(false);
    50. Log.e("定时1分钟上传数据", "$_count");
    51. }
    52. // 当时间大于计时的时间时停止计时
    53. if(getInstance()._count >= minute * 60) {
    54. getInstance()._timeState = false;
    55. if(getInstance()._timer !=null) {
    56. if(getInstance()._timer.isActive) {
    57. getInstance()._timer.cancel();
    58. }
    59. getInstance()._timer = null;
    60. Log.e("取消倒计时了", "达到时间取消的");
    61. }
    62. }
    63. });
    64. }
    65. }
    66. /// 停止计时
    67. void stopClock(bool isStop) {
    68. if(isStop) {
    69. if(getInstance()._timer !=null) {
    70. if(getInstance()._timer.isActive) {
    71. getInstance()._timer.cancel();
    72. }
    73. getInstance()._timer = null;
    74. }
    75. // 设置结束时间
    76. getInstance()._uploadTime(true);
    77. Log.e("取消倒计时了", "点击通知取消的");
    78. } else {
    79. Log.e("是开始", "不用执行特别多的操作");
    80. }
    81. }
    82. /// 设置结束上传时间
    83. /// [isStop] 是否是点击停止而进行的上传
    84. void _uploadTime(bool isStop)async {
    85. getInstance()._stopTime = DateUtil.formatDate(DateTime.now(), format: "yyyy/MM/dd HH:mm:ss");
    86. if (getInstance()._timeState == true && getInstance()._startTime != getInstance()._stopTime) {
    87. Log.e("上传数据时的计时", "$_count");
    88. /// 设置结束上传时间
    89. var memberId = await SpUtils.getInt(SaveKey.memberId);
    90. String startTime = getInstance()._startTime;
    91. String stopTime = getInstance()._stopTime;
    92. Map<String, dynamic> params = {
    93. "deviceId": getInstance()._deviceId,
    94. "memberId": "$memberId",
    95. "deviceType": "2",
    96. "startSportTime": startTime,
    97. "endSportTime":stopTime
    98. };
    99. uploadTimeModel = await ApiService.post('API/deviceUpload/uploadData', params);
    100. if (StateEnum.isNotConnection != uploadTimeModel?.state && StateEnum.success == uploadTimeModel?.state) {
    101. _uploadModel = EmptySuccessModel.fromJson(uploadTimeModel.data);
    102. if (_uploadModel?.code == 0) {
    103. Log.e("数据上传成功", '数据上传状态:${_uploadModel?.msg}');
    104. } else {
    105. Log.e("数据上传失败", '数据上传状态:${_uploadModel?.msg}');
    106. }
    107. }
    108. if (isStop) {
    109. getInstance()._timeState = false;
    110. }
    111. } else {
    112. if(isStop) {
    113. getInstance()._timeState = false;
    114. }
    115. }
    116. /// 重置上传开始上传时间
    117. getInstance()._startTime = getInstance()._stopTime;
    118. }
    119. }