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

Mor*_*ard 4 android threetenbp android-jetpack-compose android-jetpack-compose-preview

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

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

预览渲染问题堆栈跟踪:

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

Mor*_*ard 9

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

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

AndroidThreeTen.init(LocalContext.current)
Run Code Online (Sandbox Code Playgroud)

如果有一种方法可以设置一个方法作为所有预览的设置来调用,那就太好了,这可能是未来版本中值得期待的事情。

  • 有人可能会说,可预览可组合项不应该直接处理日期和时间。其他东西,例如视图模型,将处理日期/时间转换为更直接呈现的数据(例如,要显示的字符串表示形式、用于控制图标的布尔值)。这提高了可测试性,还有一个好处是不需要初始化“AndroidThreeTen”。 (3认同)