Android 从前台服务启动的线程是否持久?
Is Android thread started from foreground service persistent?
我需要一项服务,它应该 运行 24/7 执行以下功能。
(1) 每秒使用 fusedLocationApi 检查用户的 GPS,以检查用户是否进入特定的地理围栏。
(2) 检查是否安装了另一个应用程序包(线程)
(3) 按特定的 60 秒间隔向服务器发送一个活动数据包。 (线程)
线程是单例实例,因为为了电池寿命,我必须确保每个函数只有一个线程 运行。
前台服务的 onStartCommand 上的所有上述线程 运行。我读过前台服务本身在大多数情况下不会死,但线程如何?从前台服务启动的线程是否也持久存在?此外,我如何测试以证明它是持久的?
请帮忙!
我会回答我自己的问题。
大概一个月的观察和尝试,我终于得到了我想要的。
问题的答案是肯定的,但不是。线程在休眠模式下处于活动状态,但它们在内部执行的操作已暂停。
我的前台服务有一个以分钟为间隔运行的 FusedLocationProviderClient,还有一个执行其他一些工作的线程,例如以六分钟为间隔对我的服务器执行 ping 操作。他们都不会死,但是 ping 的东西有大量的延迟。它应该每六分钟 ping 服务器一次,但在打瞌睡时,它会延迟 30 分钟或更长时间,甚至超过一个小时。
我用了两种方法来解决这个问题。我不知道是哪一个使它起作用,但它仍然起作用。
(1) 添加了启动时的电池白名单。
Intent intent = PowerSaverHelper.prepareIntentForWhiteListingOfBatteryOptimization(getContext(), getPackageName(), false);
if (intent != null) {
startActivityForResult(intent, 19810);
} else {
getInterval();
}
(2) 在前台服务的 onStartCommand 上创建并保持部分唤醒锁。
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 操作,在设备未连接任何电源的情况下过夜。
但是,这种方法的失败是可以预料的。电池耗尽。通过 Battery Historian 查看时,我看到 cpu 始终处于唤醒状态,而前台服务为 运行。即使去掉 gps 的东西(它会消耗大量电池),它在一个小时的测试中也消耗了大约 0.7% 的电池。
但是,如果您的目标与我的目标相似,即一个应该持久存在的特殊用途应用程序,则此方法可能会有所帮助。
我需要一项服务,它应该 运行 24/7 执行以下功能。
(1) 每秒使用 fusedLocationApi 检查用户的 GPS,以检查用户是否进入特定的地理围栏。
(2) 检查是否安装了另一个应用程序包(线程)
(3) 按特定的 60 秒间隔向服务器发送一个活动数据包。 (线程)
线程是单例实例,因为为了电池寿命,我必须确保每个函数只有一个线程 运行。
前台服务的 onStartCommand 上的所有上述线程 运行。我读过前台服务本身在大多数情况下不会死,但线程如何?从前台服务启动的线程是否也持久存在?此外,我如何测试以证明它是持久的?
请帮忙!
我会回答我自己的问题。
大概一个月的观察和尝试,我终于得到了我想要的。
问题的答案是肯定的,但不是。线程在休眠模式下处于活动状态,但它们在内部执行的操作已暂停。
我的前台服务有一个以分钟为间隔运行的 FusedLocationProviderClient,还有一个执行其他一些工作的线程,例如以六分钟为间隔对我的服务器执行 ping 操作。他们都不会死,但是 ping 的东西有大量的延迟。它应该每六分钟 ping 服务器一次,但在打瞌睡时,它会延迟 30 分钟或更长时间,甚至超过一个小时。
我用了两种方法来解决这个问题。我不知道是哪一个使它起作用,但它仍然起作用。
(1) 添加了启动时的电池白名单。
Intent intent = PowerSaverHelper.prepareIntentForWhiteListingOfBatteryOptimization(getContext(), getPackageName(), false);
if (intent != null) {
startActivityForResult(intent, 19810);
} else {
getInterval();
}
(2) 在前台服务的 onStartCommand 上创建并保持部分唤醒锁。
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 操作,在设备未连接任何电源的情况下过夜。
但是,这种方法的失败是可以预料的。电池耗尽。通过 Battery Historian 查看时,我看到 cpu 始终处于唤醒状态,而前台服务为 运行。即使去掉 gps 的东西(它会消耗大量电池),它在一个小时的测试中也消耗了大约 0.7% 的电池。
但是,如果您的目标与我的目标相似,即一个应该持久存在的特殊用途应用程序,则此方法可能会有所帮助。