我需要运行24/7的服务,该服务具有以下功能。
(1)每秒用熔融LocationApi检查用户的GPS,以检查用户是否输入了特定的地理围栏。
(2)检查是否安装了另一个应用程序包(线程)
(3)以60秒的特定间隔将活动数据包发送到服务器。 (线程)
线程是单例实例,因为我必须确保每个函数仅运行一个线程,以延长电池寿命。
以上所有线程都在前台服务的onStartCommand上运行。我已经读到前台服务本身不会在大多数情况下消失,但是线程如何运行?从前台服务启动的线程是否也持久存在?而且,我如何测试以证明它是持久的?
请帮助!
答案 0 :(得分:1)
我会回答我自己的问题。
经过大约一个月的观察和尝试,我终于得到了想要的东西。
该问题的答案是“是”,但“否”。线程在打ze模式下仍处于活动状态,但是它们在内部执行的操作被挂起。
我的前台服务有一个以一分钟为间隔运行的FusedLocationProviderClient,以及一个执行其他工作的线程,例如以六分钟为间隔对服务器执行ping操作。他们俩都不会死,但是在ping方面有很多延迟。它应该每六分钟对服务器执行一次ping操作,但是在打do睡时,它会延迟30分钟或更长时间(甚至超过一个小时)进行ping操作。
我用两个方法来解决这个问题。我不知道是哪一个使这项工作的,但还是可以。
(1)在启动时添加了电池白名单。
Intent intent = PowerSaverHelper.prepareIntentForWhiteListingOfBatteryOptimization(getContext(), getPackageName(), false);
if (intent != null) {
startActivityForResult(intent, 19810);
} else {
getInterval();
}
(2)在Foreground服务的onStartCommand上创建并保留一个不完整的akeLock。
try {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyService::GpsWakeLock");
if (!wakeLock.isHeld()) {
wakeLock.acquire();
}
} catch (Exception e) {
ErrorController.showError(e);
}
并在前台服务的onDestroy上释放它。
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
}
此解决方案对我来说效果很好。 Gps会在一分钟内(如果可以)获取gps位置,并以确切的间隔ping服务器,整夜不间断地将设备ping通,而无需将设备未连接到任何电源。
但是,这种方法的失败是可以预期的。电池电量耗尽。通过Battery Historian进行浏览时,我看到在运行前台服务时cpu始终处于唤醒状态。即使移除gps填充物(这会消耗大量电池),在一个小时的测试中,它仍消耗了约0.7%的电池。
但是,如果您的目标与我的目标相似,那么该特殊应用程序应具有持久性,则此方法可能会有所帮助。