WorkManager 在应用关闭后停止调度周期性 Worker
Posted
技术标签:
【中文标题】WorkManager 在应用关闭后停止调度周期性 Worker【英文标题】:WorkManager stops scheduling periodic Worker after the app closes 【发布时间】:2020-02-08 10:31:59 【问题描述】:也许这是关于WorkManager的另一个问题,但我真的找不到解决方案......
正如标题所示,我正在尝试每 15 分钟运行一次定期工作。实际上,在工作人员中,我每分钟都在轮询一些数据。每次轮询后,几乎每 1 秒我检查一次工作人员是否正在停止,如果停止则返回,否则继续等待,直到达到 1 分钟并再次轮询数据。
根据文档,这应该可以工作,而且确实可以,直到我从最近的应用程序屏幕中终止该应用程序。
代码如下:
package com.qsea.app.cordova;
import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
public class ServerListenerWorker extends Worker
public static final String TAG = "ServerListenerWorker";
public ServerListenerWorker(
Context appContext,
WorkerParameters workerParams
)
super(appContext, workerParams);
@Override
public Result doWork()
Log.d(TAG, "Doing work");
final long startTime = SystemClock.elapsedRealtime();
final int maxDelta = 840000; // 14 minutes
while (true)
// I did this to stop this worker until 15 minutes
// and then let the next worker run
if (SystemClock.elapsedRealtime() - startTime >= maxDelta)
break;
// Here I'm polling data, if the polling results in a failure
// I return Result.retry()
// It avoid waiting if it remains only 1 minute until the max time
if (SystemClock.elapsedRealtime() - startTime >= (maxDelta - 60000))
break;
for (int i = 0; i < 60; i++)
SystemClock.sleep(950);
// Here it checks if it is stopped
if (isStopped())
Log.d(TAG, "Detected stop"); // this is actually never reached
break;
return Result.success();
我按照以下步骤开始工作
Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(ServerListenerWorker.class, 15, TimeUnit.MINUTES)
.addTag(serverListenerWorkerUID)
.setConstraints(constraints)
.build();
WorkManager.getInstance(cordova.getActivity()).enqueueUniquePeriodicWork(serverListenerWorkerUID, ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
我通过查看我的服务器日志来检查工作人员的正常工作(如果我收到请求,它工作正常),它似乎工作正常,直到我关闭应用程序。然后它停止运行实际的工作程序,并且在我重新打开应用程序之前不再运行工作程序,工作似乎已排队并在应用程序打开后立即恢复。
我在初始化时做错了吗?
我的 AndroidManifest.xml 中也有 <service android:name=".ServerListenerWorker" android:permission="android.permission.BIND_JOB_SERVICE" />
这是预期的行为吗?
我读到中文ROM对后台服务有额外的限制,我有一个华为,这似乎是最糟糕的。那么它可能是设备吗?如果是这样,Facebook、WhatsApp、Instagram 和其他人如何管理它以使其即使在这些设备中也能正常工作?
【问题讨论】:
在市场上和实际设备上都会发生。由于实际设备不是库存的 android 手机,而是来自中国制造商。他们定制了停止所有其他进程,并在应用程序关闭时只保留他们自己的、google、whatsapp、facebook。这是一个很长的故事,我已经经历了。 对此有什么办法?我只是试图忽略对我的应用程序的优化,但没有任何改变...... @GC,如果您的代码是完美的(在一组模拟器和三星、索尼等实际标准设备上运行良好),那么您可以尝试更改手机的自定义设置,专门针对 ColorOs 等中文修改过的 rom, MUIUI、OxygenOS、Fun2Os 这个列表永无止境 我正在做一些测试,我设法让它工作,调整电池优化设置。我正在尝试找到一种以编程方式解决此问题的解决方案(不是自动,而是要求用户进行这些更改)。如果我找到任何可行的方法,我会写一个解决方案 好的,我写了这段代码:Activity activity = cordova.getActivity(); activity.startActivityForResult(new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS), ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS_RESULT);
, onActivityResult 我使用之前引用的技术再次调用 startActivityResult,在用户标记应用程序忽略电池优化后,我启动了工作程序。这应该附有解释,以便用户了解该做什么。但是,在华为 P smart 2019 中测试,它可以工作!我会尽快清除代码并回答这个问题。
【参考方案1】:
让我们把它分成两个不同的问题。
您在工作人员中执行的操作会消耗大量电量,如果您使用前台服务来通知用户您的应用程序在后台连续运行会更好。您还可以将 WorkManager 与新引入的对长时间运行的工作人员的支持一起使用(在后台使用前台服务)。 More on this in the documentation。
如果特定 OEM 有问题,请open an issue on the Android issuetracker,因为这可能违反了 CDD。 Google 可以联系 OEM 并要求他们修复 ROM。这需要时间,与此同时,您可以查看don't kill my app 之类的网站以了解特定设备上的限制,并使用autostarter 之类的库来帮助用户导航到正确的设置.
顺便说一句,您不需要在 AndroidManifest.xml
文件中列出您的工人
【讨论】:
谢谢,我试试 AutoStarter!以上是关于WorkManager 在应用关闭后停止调度周期性 Worker的主要内容,如果未能解决你的问题,请参考以下文章