升级到WorkManager 2.7.0:如何实现getForegroundInfoAsync为RxWorker?<



我的应用程序是针对API 31/Android 12和版本2.7.0的WorkManager是必需的,根据谷歌,所以为了做到这一点,我已经添加了setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)到我的OneTimeWorkRequestBuilder,并在AndroidManifest中添加了必要的更改,以及(参见此链接了解详细信息)。然而,当我运行我的应用程序时,我遇到了这个错误:

java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Expedited WorkRequests require a ListenableWorker to provide an implementation for `getForegroundInfoAsync()`

谷歌没有提供关于如何为RxWorker做到这一点的示例或文档,但我在Stackoverflow中找到了这个答案,但它是针对协程的。

我的问题是当getForegroundInfoAsync必须返回ListenableFuture<ForegroundInfo>时,如何实现RxWorkergetForegroundInfoAsync-阅读文档似乎我必须将番石榴添加到我的应用程序中才能做到这一点?因为ListenableFuture的文档对Avoid implementing ListenableFuture from scratch. If you can't get by with the standard implementations, prefer to derive a new Future instance with the methods in Futures or, if necessary, to extend AbstractFuture.

另一种不需要受限API或导入期货库的方法是使用Futures.immediateFuture()方法:

override fun getForegroundInfoAsync(): ListenableFuture<ForegroundInfo> {
val notificationId = // some int id for your notification
val notification = // build your notification in the normal way
return Futures.immediateFuture(ForegroundInfo(notificationId, notification))
}

编辑:目前,有两种方法可以做到这一点:

1。使用受限API

查看ListenableWorker的源代码,我们发现getForegroundInfoAsync是这样的:

@NonNull
public ListenableFuture<ForegroundInfo> getForegroundInfoAsync() {
SettableFuture<ForegroundInfo> future = SettableFuture.create();
String message =
"Expedited WorkRequests require a ListenableWorker to provide an implementation for"
+ " `getForegroundInfoAsync()`";
future.setException(new IllegalStateException(message));
return future;
}

所以在我自己的RxWorker的getForegroundInfoAsync的实现中,我尝试创建一个SettableFuture,但我看到一个lint警告告诉我SettableFuture的使用在其库中受到限制。但这可以通过用@SuppressLint("RestrictedApi")注释实现getForegroundInfoAsync来绕过。下面是我的代码的大致样子:

@SuppressLint("RestrictedApi")
override fun getForegroundInfoAsync(): ListenableFuture<ForegroundInfo> {
val future = SettableFuture.create<ForegroundInfo>()
val notificationId = id.hashCode()
val fileName = inputData.getString(KEY_OUTPUT_FILE_NAME)
if (fileName == null) {
future.setException(IllegalStateException("Filename is null"))
return future
}
val notificationBuilder = getNotificationBuilder(fileName)
future.set(ForegroundInfo(notificationId, notificationBuilder.build()))
return future
}

2。使用CallbackToFutureAdapter

你可以使用CallbackToFutureAdapter而不是依赖于受限的API,但是这个解决方案需要Futures AndroidX库,见这里的链接。将上述库添加到项目后,您可以使用CallbackToFutureAdapter以这种方式返回ListenableFuture:

override fun getForegroundInfoAsync(): ListenableFuture<ForegroundInfo> {
val fileName = inputData.getString(KEY_OUTPUT_FILE_NAME)
return CallbackToFutureAdapter.getFuture {
if (fileName == null) {
it.setException(IllegalStateException("Filename is null"))
} else {
notificationBuilder = getNotificationBuilder(fileName)
it.set(ForegroundInfo(notificationId, notificationBuilder.build()))
}
}
}

有一个警告,当为你的通知创建PendingIntent时,不要忘记设置PendingIntent.FLAG_MUTABLE标志(详细信息请参阅此回答)

相关内容

  • 没有找到相关文章