Jetpack Compose 预览失败,来自 ThreeTen 的 LocalDate.now()

Jetpack Compose Preview failing with LocalDate.now() from ThreeTen

当我们有一些代码从中调用 LocalDate.now() 时,渲染 Jetpack Compose 预览失败。我们已尝试在预览中设置语言环境,但这没有帮助,而且我们还没有找到任何其他方法来在预览中设置上下文信息。

我们怎样才能做到这一点?

预览渲染问题堆栈跟踪:

org.threeten.bp.zone.ZoneRulesException: No time-zone data files registered at org.threeten.bp.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:165) at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:122) at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143) at org.threeten.bp.ZoneId.of(ZoneId.java:358) at org.threeten.bp.ZoneId.of(ZoneId.java:286) at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:245) at org.threeten.bp.Clock.systemDefaultZone(Clock.java:137) at org.threeten.bp.LocalDate.now(LocalDate.java:165) at xxx.ui.shared.formatter.OrderDateFormatter.getFormattedTimes(OrderDateFormatter.kt:12) at xxx.model.Pickup.displayCreatedTime(Pickup.kt:55) at xxx.ui.orderStatus.pickups.PickupsListKt.DateRows(PickupsList.kt:268) at xxx.ui.orderStatus.pickups.PickupsListKt.PickupPanelDetails(PickupsList.kt:129) at xxx.ui.orderStatus.pickups.PickupsListKt.PickupPanel(PickupsList.kt:78) at xxx.ui.orderStatus.pickups.PickupsListKt$PickupsList.invoke(PickupsList.kt:51) at xxx.ui.orderStatus.pickups.PickupsListKt$PickupsList.invoke(PickupsList.kt:49) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at xxx.ui.shared.composables.LoadingComposableKt.LoadingComposable(LoadingComposable.kt:39) at xxx.ui.orderStatus.pickups.PickupsListKt.PickupsList(PickupsList.kt:49) at xxx.ui.orderStatus.pickups.ComposableSingletons$PickupsListKt$lambda-1.invoke(PickupsList.kt:337) at xxx.ui.orderStatus.pickups.ComposableSingletons$PickupsListKt$lambda-1.invoke(PickupsList.kt:336) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at xxx.ui.shared.appTheme.AppThemeKt$AppTheme.invoke(AppTheme.kt:56) at xxx.ui.shared.appTheme.AppThemeKt$AppTheme.invoke(AppTheme.kt:55) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215) at androidx.compose.material.TextKt.ProvideTextStyle(Text.kt:252) at androidx.compose.material.MaterialThemeKt$MaterialTheme.invoke(MaterialTheme.kt:81) at androidx.compose.material.MaterialThemeKt$MaterialTheme.invoke(MaterialTheme.kt:80) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215) at androidx.compose.material.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:72) at xxx.ui.shared.appTheme.AppThemeKt.AppTheme(AppTheme.kt:55) at xxx.ui.orderStatus.pickups.PickupsListKt.DefaultPickupsListPreview(PickupsList.kt:336) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at androidx.compose.ui.tooling.CommonPreviewUtils.invokeComposableMethod(CommonPreviewUtils.kt:149) at androidx.compose.ui.tooling.CommonPreviewUtils.invokeComposableViaReflection$ui_tooling_release(CommonPreviewUtils.kt:188) at androidx.compose.ui.tooling.ComposeViewAdapter$init$composable.invoke(ComposeViewAdapter.kt:571) at androidx.compose.ui.tooling.ComposeViewAdapter$init$composable.invoke(ComposeViewAdapter.kt:569) at androidx.compose.ui.tooling.ComposeViewAdapter$init.invoke(ComposeViewAdapter.kt:608) at androidx.compose.ui.tooling.ComposeViewAdapter$init.invoke(ComposeViewAdapter.kt:564) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215) at androidx.compose.ui.tooling.InspectableKt.Inspectable(Inspectable.kt:64) at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview.invoke(ComposeViewAdapter.kt:513) at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview.invoke(ComposeViewAdapter.kt:512) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215) at androidx.compose.ui.tooling.ComposeViewAdapter.WrapPreview(ComposeViewAdapter.kt:508) at androidx.compose.ui.tooling.ComposeViewAdapter.access$WrapPreview(ComposeViewAdapter.kt:121) at androidx.compose.ui.tooling.ComposeViewAdapter$init.invoke(ComposeViewAdapter.kt:564) at androidx.compose.ui.tooling.ComposeViewAdapter$init.invoke(ComposeViewAdapter.kt:561) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:384) at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated.invoke(ComposeView.android.kt:228) at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated.invoke(ComposeView.android.kt:227) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215) at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:148) at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals.invoke(AndroidCompositionLocals.android.kt:114) at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals.invoke(AndroidCompositionLocals.android.kt:113) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215) at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:106) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:162) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:161) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:161) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:144) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.ComposerKt.invokeComposable(Composer.kt:3336) at androidx.compose.runtime.ComposerImpl$doCompose.invoke(Composer.kt:2583) at androidx.compose.runtime.ComposerImpl$doCompose.invoke(Composer.kt:2579) at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotState.kt:540) at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2572) at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:2523) at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:476) at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:727) at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:432) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:144) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:135) at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:733) at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:135) at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:187) at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354) at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:196) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:142) at androidx.compose.ui.platform.WrappedComposition$setContent.invoke(Wrapper.android.kt:135) at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:820) at android.view.View.dispatchAttachedToWindow(View.java:20479) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3489) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496) at android.view.AttachInfo_Accessor.setAttachInfo(AttachInfo_Accessor.java:44) at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:360) at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:431) at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:141) at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:714) at com.android.tools.idea.rendering.RenderTask.lambda$inflate(RenderTask.java:870) at com.android.tools.idea.rendering.RenderExecutor$runAsyncActionWithTimeout.run(RenderExecutor.kt:187) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834)

发布问题后,我们找到了解决方案。

只需在需要它的每个预览方法的开头添加这一行:

AndroidThreeTen.init(LocalContext.current)

最好能有一种方法来设置一个方法作为所有预览的设置调用,这可能是即将发布的版本所希望的。