【发布时间】:2019-10-16 18:03:46
【问题描述】:
我正在使用AndroidX Work Dependency 尝试运行一些后台服务操作。在发布此问题时,我目前正在运行最新的稳定版本 2.2.0。
我在后台运行的实际操作是一个相当繁重的 CPU 操作,因为它在我的一个库 (here) 中使用了一些压缩代码,并且可能需要 3-30 分钟,具体取决于大小和相关视频的长度。
这是我构建和运行工作请求的代码:
public static void startService(){
//Create the Work Request
String uniqueTag = "Tag_" + new Date().getTime() + "_ChainVids";
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(CompleteVideoBackgroundService.class);
Constraints.Builder constraints = new Constraints.Builder();
constraints.setRequiredNetworkType(NetworkType.CONNECTED);
builder.setConstraints(constraints.build());
builder.setInitialDelay(1, TimeUnit.MILLISECONDS);
builder.addTag(uniqueTag);
Data inputData = new Data.Builder().putString("some_key", mySerializedJSONString).build();
builder.setInputData(inputData);
OneTimeWorkRequest compressRequest = builder.build();
//Set the Work Request to run
WorkManager.getInstance(MyApplication.getContext())
.beginWith(compressRequest)
.enqueue();
}
然后它会触发这个运行所有后台服务操作的类:
public class MyServiceSampleForStackoverflow extends Worker {
private Context context;
private WorkerParameters params;
public MyServiceSampleForStackoverflow(@NonNull Context context, @NonNull WorkerParameters params){
super(context, params);
this.context = context;
this.params = params;
}
/**
* Trimming this code down considerably, but the gist is still here
*/
@NonNull
@Override
public Result doWork() {
try {
//Using using a hard-coded 50% for this SO sample
float percentToBringDownTo = 0.5F;
Uri videoUriToCompress = MyCustomCode.getVideoUriToCompress();
VideoConversionProgressListener listener = (progressPercentage, estimatedNumberOfMillisecondsLeft) -> {
float percentComplete = (100 * progressPercentage);
//Using this value to update the Notification Bar as well as printing in the logcat. Erroneous code removed
};
String newFilePath = MyCustomCode.generateNewFilePath();
//The line below this is the one that takes a while as it is running a long operation
String compressedFilePath = SiliCompressor.with(MyApplication.getContext()).compressVideo(
listener, videoUriToCompress.getPath(), newFilePath, percentToBringDownTo);
//Do stuff here with the compressedFilePath as it is now done
return Result.success();
} catch (Exception e){
e.printStackTrace();
return Result.failure();
}
}
}
偶尔,在没有任何押韵或理由的情况下,工人在没有我告诉它的情况下随机停止。发生这种情况时,我会看到此错误:
Work [ id=254ae962-114e-4088-86ec-93a3484f948d, tags={ Tag_1571246190190_ChainVids, myapp.packagename.services.MyServiceSampleForStackoverflow } ] was cancelled
java.util.concurrent.CancellationException: Task was cancelled.
at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1184)
at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:514)
at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:284)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
当这种随机发生时,我实际上只是盯着我的手机看,根本不与它互动。我不想运行其他应用程序,也不想占用 CPU 做其他事情。我从来没有看到我自己的任何堆栈跟踪,也没有直接的问题或原因是可见的。
因此,问题是,这里发生了什么随机停止 Worker 服务而没有任何挑衅? 为什么会随机停止操作?
谢谢大家。
编辑 1
我确实测试了删除可能导致问题的网络约束要求行,并且我确实看到它甚至在那之后发生,所以我不认为这是问题所在。
我正在 Google Pixel 3、API 28、Android 9 上进行测试,但我测试过的任何其他设备(无论 API 级别如何(支持的最低级别为 21))都显示出同样的问题。
编辑 2
- 我尝试通过让类扩展
ListenableWorker而不是Worker来重写类以使用异步方法,但这并没有解决问题。
【问题讨论】:
-
你在什么操作系统版本和设备/模拟器上测试。
-
我更新了底部的问题,感谢莫里森的提问!
-
我也有同样的问题
标签: java android android-service androidx