Android Jetpack Tile抛出Java.util.concurrent.cancellation exception
我正在开发一个Android Wear Tile,偶尔会以此堆栈跟踪崩溃。
2022-06-22 15:19:24.753 24101-24101/myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: myapp, PID: 24101
java.util.concurrent.CancellationException
at kotlinx.coroutines.guava.JobListenableFuture.getInternal(ListenableFuture.kt:438)
at kotlinx.coroutines.guava.JobListenableFuture.get(ListenableFuture.kt:428)
at androidx.wear.tiles.TileService$TileProviderWrapper.lambda$onTileRequest$0(TileService.java:234)
at androidx.wear.tiles.TileService$TileProviderWrapper$$ExternalSyntheticLambda7.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:7690)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
Caused by: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelled}@d298571
我认为这是当我的瓷砖令人耳目一新的时候发生。我的瓷砖是使用Raturofit从REST API获取数据。该代码看起来像这样:
class WeatherTileService : TileService() {
private val serviceScope = CoroutineScope(Dispatchers.IO)
override fun onTileRequest(requestParams: TileRequest) = serviceScope.future {
Log.d("Tile", "Refreshing weather data")
val api = AmbientWeatherClient.getInstance()
val devices = api.listUsersDevices(APP_KEY, API_KEY)
...
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setFreshnessIntervalMillis(5 * 60 * 1000)
.setTimeline(
interface AmbientWeatherAPI {
@GET("devices")
suspend fun listUsersDevices(
@Query("applicationKey") applicationKey: String,
@Query("apiKey") apiKey: String
): List<Device>
}
我不知道为什么会发生这种情况。有什么建议从哪里开始挖掘?
I am developing an Android Wear Tile and occasionally my app crashes with this stack trace.
2022-06-22 15:19:24.753 24101-24101/myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: myapp, PID: 24101
java.util.concurrent.CancellationException
at kotlinx.coroutines.guava.JobListenableFuture.getInternal(ListenableFuture.kt:438)
at kotlinx.coroutines.guava.JobListenableFuture.get(ListenableFuture.kt:428)
at androidx.wear.tiles.TileService$TileProviderWrapper.lambda$onTileRequest$0(TileService.java:234)
at androidx.wear.tiles.TileService$TileProviderWrapper$ExternalSyntheticLambda7.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:7690)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
Caused by: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelled}@d298571
I think this is occurring when my tile is refreshing. My tile is getting data from a REST API using Retrofit. The code looks something like this:
class WeatherTileService : TileService() {
private val serviceScope = CoroutineScope(Dispatchers.IO)
override fun onTileRequest(requestParams: TileRequest) = serviceScope.future {
Log.d("Tile", "Refreshing weather data")
val api = AmbientWeatherClient.getInstance()
val devices = api.listUsersDevices(APP_KEY, API_KEY)
...
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setFreshnessIntervalMillis(5 * 60 * 1000)
.setTimeline(
interface AmbientWeatherAPI {
@GET("devices")
suspend fun listUsersDevices(
@Query("applicationKey") applicationKey: String,
@Query("apiKey") apiKey: String
): List<Device>
}
I cannot figure out why this is happening. Any suggestions where to start digging?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我感到惊讶的是,取消杀死了您的应用程序。但是您有一个10秒钟的窗口来完成该请求。我怀疑这是取消。
我的建议将永远不会在NittilereQuest上进行任何可变长度工作,例如调用远程API。从缓存(例如房间数据库)提供服务通常更有意义。
同样,当瓷砖请求进来时可能无法使用网络。由于这个和许多其他原因,通常最好拥有一些背景过程更新数据,例如Workmanager。然后,这可以将更新发送给您的瓷砖,也可以将任何复杂性或应用本身发送。
I am surprised the cancellation kills your app. But you have a window of 10 seconds to complete that request. I suspect this is the cancellation.
My advice would be never do any variable length work in onTileRequest, such as calling a remote API. It generally makes more sense to be serving this from a cache, such as a Room database.
Also the network may not be available when the tile request comes in. For this and many other reasons, it's typically better to have some background process updating data, such as WorkManager. This can then send an update to your Tile, but also any complications or the App itself.