Я работаю с AndroidX Work Dependency , чтобы попытаться выполнить некоторые операции фонового сервиса. В настоящее время я использую самую последнюю стабильную версию, 2.2.0
на момент публикации этого вопроса.
Фактическая операция, которую я выполняю в фоновом режиме, является довольно тяжелой операцией ЦП, поскольку она использует некоторый код сжатия в одноммоих библиотек ( здесь ) и может занять от 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)
Я буквально просто смотрю на свой телефон и вообще не взаимодействую с ним, когда это происходит случайно. Я не пытаюсь запускать другие приложения, и при этом я не пытаюсь загружать процессор для чего-то другого. Я никогда не вижу своих собственных стековых трасс и не вижу никаких непосредственных проблем или причин.
Следовательно, вопрос в том, что здесь происходит, что случайным образом останавливает службу Worker без какой-либо провокации? Почему происходит произвольная остановка операций?
Спасибо всем.
РЕДАКТИРОВАТЬ 1
Я тестировал удаление строки требований сетевых ограничений, думая, что это может быть причиной проблемы, и я видел, что это происходит даже после этого, поэтому я не верю, что это проблема.
Я тестирую на Google Pixel 3, API 28, Android 9, но на любом другом устройстве, которое я тестировал, независимо от уровня API (минимум поддерживается 21), возникла та же проблема.
Редактировать 2
- Я попытался переписать класс для работы в асинхронном подходе, расширив класс
ListenableWorker
вместоWorker
и это не решило проблему.