JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.59k stars 1.14k forks source link

MissingResourceException: fail to read HTML file on Android #3819

Closed KevinnZou closed 1 month ago

KevinnZou commented 9 months ago

Describe the bug In my project https://github.com/KevinnZou/compose-webview-multiplatform. It has a webview module and a sample module depending on the webview module. I implemented a logic in the webview module that will read the HTML file under the resources folder and load it by Webview.

  @OptIn(ExperimentalResourceApi::class)
  suspend fun loadHtmlFile(fileName: String) {
      val res = resource(fileName)
      val html = res.readBytes().decodeToString().trimIndent()
      loadHtml(html, encoding = "utf-8")
  }

Then, I placed an index.html file under the sample/shared/commonMain/resources folder and called that method from the sample module. It works well on the Desktop and iOS platforms but failed on Android with the error:org.jetbrains.compose.resources.MissingResourceException: Missing resource with path: index.html

It works if I also create a index.html file under the webview/commonMain/resources folder. However, it is impossible for developers to place their resource files under my library folder. Webview module will be published as a dependency and need to read the resource under the host project's resources folder.

Affected platforms Select one of the platforms below:

Versions

To Reproduce Steps and/or the code snippet to reproduce the behavior:

  1. Clone the project code on this branch
  2. run sample.android app
  3. See error

Expected behavior index.html file under the sample/shared/commonMain/resources should be loaded successfully

Additional context Full Stacktrace:

FATAL EXCEPTION: main
                                                                                                    Process: com.multiplatform.webview, PID: 12045
                                                                                                    org.jetbrains.compose.resources.MissingResourceException: Missing resource with path: index.html
                                                                                                        at org.jetbrains.compose.resources.AndroidResourceImpl.readBytes(Resource.android.kt:21)
                                                                                                        at com.multiplatform.webview.web.IWebView$DefaultImpls.loadHtmlFile(IWebView.kt:50)
                                                                                                        at com.multiplatform.webview.web.AndroidWebView.loadHtmlFile(AndroidWebView.kt:15)
                                                                                                        at com.multiplatform.webview.web.WebViewKt$WebView$3$2$2.emit(WebView.kt:60)
                                                                                                        at com.multiplatform.webview.web.WebViewKt$WebView$3$2$2.emit(WebView.kt:42)
                                                                                                        at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
                                                                                                        at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
                                                                                                        at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:87)
                                                                                                        at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:66)
                                                                                                        at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invokeSuspend(SnapshotFlow.kt:133)
                                                                                                        at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invoke(Unknown Source:8)
                                                                                                        at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invoke(Unknown Source:4)
                                                                                                        at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:61)
                                                                                                        at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:230)
                                                                                                        at com.multiplatform.webview.web.WebViewKt$WebView$3$2.invokeSuspend(WebView.kt:42)
                                                                                                        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                                                                                                        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:938)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loop(Looper.java:223)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7656)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
                                                                                                        Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@69956f, androidx.compose.runtime.BroadcastFrameClock@b56a27c, StandaloneCoroutine{Cancelling}@14d2705, AndroidUiDispatcher@29b535a]
terrakok commented 1 month ago

For multiplatform resources you are supposed to use https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-images-resources.html

okushnikov commented 2 weeks ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.