Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compose resources don't work in the Android Studio Preview #4476

Closed
exdrcw opened this issue Mar 13, 2024 · 13 comments · Fixed by #4965
Closed

Compose resources don't work in the Android Studio Preview #4476

exdrcw opened this issue Mar 13, 2024 · 13 comments · Fixed by #4965
Assignees
Labels
android studio bug Something isn't working preview resources wontfix This will not be worked on

Comments

@exdrcw
Copy link

exdrcw commented Mar 13, 2024

This bug only appears in Android, but since it is related to multi-platform resources and the exception comes from org.jetbrains.compose.resources, I create a report here

Describe the bug
Unable to use Android live preview for Composable functions that use multi-platform resources.

In a Compose multi-platform project, I am able to use android live preview for composable functions that do not use multi-platform resources.
But when the composable function use multi-platform resources, the preview rendering will report an error

Affected platforms

  • Android

Versions

  • Kotlin version*: 1.9.22
  • Compose Multiplatform version*: 1.6.0
  • OS version(s)* (required for Desktop and iOS issues):
  • OS architecture (x86 or arm64):
  • Device (model or simulator for iOS issues):
  • JDK (for desktop issues):

Android Studio Versions
Android Studio Hedgehog | 2023.1.1 Patch 2
Build #AI-231.9392.1.2311.11330709, built on January 19, 2024
Runtime version: 17.0.7+0-b2043.56-10550314 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 11.0
Non-Bundled Plugins:
com.jetbrains.kmm (0.8.2(231)-25)
org.jetbrains.compose.desktop.ide (1.6.0)

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

  1. Use Kotlin Multiplatform wizard create a new project, Only includes android and desktop platforms
  2. Open the project using Android Studio and add the following content under build.gradle.kts under composeApp
  3. In Android block:
    buildFeatures {
        compose = true
    }
    composeOptions{
        kotlinCompilerExtensionVersion = "1.5.10"
    }

to enable android real-time preview
4. gradle sync
5. go to commonMain/kotlin/App.kt
6. Change

var showContent by remember { mutableStateOf(false) }

to

var showContent by remember { mutableStateOf(true) }

so that the image can be displayed by default
8. go to androidMain/kotlin/packagename/MainActivity.kt
9. open preview window
10. click Build & Refresh
11. You will see "Render problem"

Expected behavior
The preview will render normally and the Composable UI can be seen

Screenshots
{5B5F991D-3FB0-483f-99B9-5475A0C1D9C6}

Additional context
Rendering problem stack information:

org.jetbrains.compose.resources.MissingResourceException: Missing resource with path: drawable/compose-multiplatform.xml
	at org.jetbrains.compose.resources.ResourceReader_androidKt.readResourceBytes(ResourceReader.android.kt:16)
	at org.jetbrains.compose.resources.ResourceReaderKt$DefaultResourceReader$1.read(ResourceReader.kt:23)
	at org.jetbrains.compose.resources.ImageResourcesKt$loadImage$2$deferred$1$1$1.invokeSuspend(ImageResources.kt:134)
	at _layoutlib_._internal_.kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at _layoutlib_._internal_.kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at _layoutlib_._internal_.kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280)
	at _layoutlib_._internal_.kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at _layoutlib_._internal_.kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at _layoutlib_._internal_.kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at _layoutlib_._internal_.kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at _layoutlib_._internal_.kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at org.jetbrains.compose.resources.ResourceState_blockingKt.rememberResourceState(ResourceState.blocking.kt:15)
	at org.jetbrains.compose.resources.ImageResourcesKt.vectorResource(ImageResources.kt:99)
	at org.jetbrains.compose.resources.ImageResourcesKt.painterResource(ImageResources.kt:56)
	at ComposableSingletons$AppKt$lambda-2$1.invoke(App.kt:31)
	at ComposableSingletons$AppKt$lambda-2$1.invoke(App.kt:28)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:118)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.animation.AnimatedVisibilityKt.AnimatedEnterExitImpl(AnimatedVisibility.kt:818)
	at androidx.compose.animation.AnimatedVisibilityKt.AnimatedVisibilityImpl(AnimatedVisibility.kt:741)
	at androidx.compose.animation.AnimatedVisibilityKt.AnimatedVisibility(AnimatedVisibility.kt:283)
	at ComposableSingletons$AppKt$lambda-3$1.invoke(App.kt:28)
	at ComposableSingletons$AppKt$lambda-3$1.invoke(App.kt:22)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.material.MaterialTheme_androidKt.PlatformMaterialTheme(MaterialTheme.android.kt:23)
	at androidx.compose.material.MaterialThemeKt$MaterialTheme$1$1.invoke(MaterialTheme.kt:82)
	at androidx.compose.material.MaterialThemeKt$MaterialTheme$1$1.invoke(MaterialTheme.kt:81)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:248)
	at androidx.compose.material.TextKt.ProvideTextStyle(Text.kt:396)
	at androidx.compose.material.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:81)
	at androidx.compose.material.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:80)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.material.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:72)
	at AppKt.App(App.kt:22)
	at xyz.hentaiguys.htgapp.MainActivityKt.AppAndroidPreview(MainActivity.kt:23)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at androidx.compose.ui.tooling.ComposableInvoker.invokeComposableMethod(ComposableInvoker.jvm.kt:181)
	at androidx.compose.ui.tooling.ComposableInvoker.invokeComposable(ComposableInvoker.jvm.kt:221)
	at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.android.kt:504)
	at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.android.kt:502)
	at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.android.kt:539)
	at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.android.kt:497)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.ui.tooling.InspectableKt.Inspectable(Inspectable.android.kt:61)
	at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.android.kt:444)
	at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.android.kt:443)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.ui.tooling.ComposeViewAdapter.WrapPreview(ComposeViewAdapter.android.kt:438)
	at androidx.compose.ui.tooling.ComposeViewAdapter.access$WrapPreview(ComposeViewAdapter.android.kt:124)
	at androidx.compose.ui.tooling.ComposeViewAdapter$init$3.invoke(ComposeViewAdapter.android.kt:497)
	at androidx.compose.ui.tooling.ComposeViewAdapter$init$3.invoke(ComposeViewAdapter.android.kt:494)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:428)
	at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:252)
	at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:251)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:186)
	at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:119)
	at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:118)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:110)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:139)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:138)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:248)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:138)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:123)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:90)
	at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3302)
	at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3235)
	at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:725)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1071)
	at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:633)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:619)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:123)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:114)
	at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1289)
	at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:114)
	at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:164)
	at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
	at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.kt:192)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:121)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:114)
	at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:1364)
	at android.view.View.dispatchAttachedToWindow(View.java:21291)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3491)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498)
	at android.view.AttachInfo_Accessor.setAttachInfo(AttachInfo_Accessor.java:54)
	at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:372)
	at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:450)
	at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:122)
	at com.android.tools.rendering.RenderTask.createRenderSession(RenderTask.java:742)
	at com.android.tools.rendering.RenderTask.lambda$inflate$7(RenderTask.java:889)
	at com.android.tools.rendering.RenderExecutor$runAsyncActionWithTimeout$3.run(RenderExecutor.kt:202)
	at com.android.tools.rendering.RenderExecutor$PriorityRunnable.run(RenderExecutor.kt:316)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

@exdrcw exdrcw added bug Something isn't working submitted labels Mar 13, 2024
@eymar eymar added resources and removed submitted labels Mar 13, 2024
@terrakok
Copy link
Collaborator

terrakok commented Mar 13, 2024

It seems like the AndroidStudio's composable preview doesn't support Java resources:
(that is a pure Android project)

image

Though an app works fine:
image

@terrakok
Copy link
Collaborator

@tamtom
Copy link

tamtom commented Mar 27, 2024

This didn't resolve any issue

@danielesegato
Copy link

This should not be closed until it works in android studio. Or at least we should have a bug on Android studio about it

@terrakok
Copy link
Collaborator

This is 3party problem. We will not fix it. So, I closed the issue.
We work on the compose resources support in the Fleet IDE

@comm1x
Copy link

comm1x commented Apr 30, 2024

Well, actually it also not working in Fleet 1.33.
I'm not sure it is only 3rd party problem.

image image

And in running app resources works correctly.

@terrakok
Copy link
Collaborator

@boiler23
Copy link

I believe this is the right issue to track: https://youtrack.jetbrains.com/issue/FL-25048

@terrakok terrakok changed the title Unable to use Android live preview for Composable functions that use multi-platform resources Compose resources don't work in the Android Studio Preview Jun 6, 2024
@rschattauer
Copy link

@terrakok , isn't this repository also for the IntelliJ plugin? If yes this issue would still be valid, no?

@terrakok
Copy link
Collaborator

terrakok commented Jun 18, 2024

Do you mean the compose IntelliJ plugin? It works for desktop java previews, I guess.

@rschattauer
Copy link

Yes. And how about compose multiplatform preview annotations, not the desktop annotation workaround?

@terrakok
Copy link
Collaborator

compose multiplatform preview annotations

It is supported in the Fleet only

@terrakok
Copy link
Collaborator

#4965

terrakok added a commit that referenced this issue Jun 20, 2024
The PR changes the android resources packaging. Now all resources are
packed to the android assets (not only fonts). It unblocks usage android
URIs to the resources in a WebView or other external resource consumers.
Additionally the PR fixes Android Studio Compose Previews work with
multiplatform resources:


![](https://private-user-images.githubusercontent.com/3532155/341182790-ef26b667-ad0d-4efd-b7f9-23cff92ab49d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTg4Nzg0MTgsIm5iZiI6MTcxODg3ODExOCwicGF0aCI6Ii8zNTMyMTU1LzM0MTE4Mjc5MC1lZjI2YjY2Ny1hZDBkLTRlZmQtYjdmOS0yM2NmZjkyYWI0OWQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDYyMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA2MjBUMTAwODM4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9OTY1MzdhMTAxMjNmZDRhMDA4ZjdjODBjYzg3M2MyNDg0ZTA5OWFkZGZkZjk1ZDUwOWFkZDk3MmQ2YjIzNzJiYiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.xgUAr_2--ZHo6txhdAANRbe8ju2SQ5EACvK96gaGJnY)

For a backward compatibility the resources library tries to read
resources in java resources if assets were not found.

Fixes #4877
Fixes #4503
Fixes #4932
Fixes #4476

## Release Notes

### Features - Resources
- Android Studio Preview works with Compose Multiplatform resources now
- Compose Multiplatform resources are stored in the android assets now.
This fixes such cases as a rendering resource files in WebViews or Media
Players
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android studio bug Something isn't working preview resources wontfix This will not be worked on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants