也许这是关于WorkManager的又一个问题,但我真的找不到解决方案...
正如标题所示,我正在尝试每15分钟运行一次定期工作。 实际上,在worker中,我每分钟轮询一些数据。 在每次轮询后,几乎每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);
我通过查看服务器日志来检查worker是否正常运行(如果我收到请求,它就可以正常工作),直到我关闭应用程序时,似乎它工作得很好。然后它停止运行实际的worker并且在重新打开应用程序之前永远不会再次运行worker,当应用程序打开时,工作似乎被排队并在应用程序打开后立即恢复。
我在初始化中做错了些什么吗? 我还在我的AndroidManifest.xml文件中加入了
<service android:name=".ServerListenerWorker" android:permission="android.permission.BIND_JOB_SERVICE" />
。这是预期的行为吗?
我读到中国ROM对后台服务有额外的限制,我有一个华为手机,似乎是最差的情况。那么这可能是设备的原因吗?如果是这样,Facebook、WhatsApp、Instagram和其他公司如何在这些设备上实现工作?
Activity activity = cordova.getActivity(); activity.startActivityForResult(new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS), ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS_RESULT);
,在onActivityResult中,我再次使用之前提到的技术调用startActivityResult,并且在用户标记应用程序以忽略电池优化后,启动worker。这应该附有一个说明,让用户理解该怎么做。但是,在华为P smart 2019上测试过,它可以工作!我很快就会清除代码并回答这个问题。 - Giuliano Collacchioni