intellij
intellij copied to clipboard
Support Jetpack Compose previews in Android Studio
Currently when you import an Android Studio project that builds an app using Jetpack Compose UI, it will fail to display compose previews.
The expected behavior is that Android Studio should recognize when a Kotlin file contains a composable @Preview
and open the compose designer plugin shown here.
I was recently experimenting with the compose preview and was able to get it working locally, this would require a couple of changes upstream.
The issues I've found:
-
Wrong
ComposeViewAdapter
is being usedThere are two compose namespaces (see definition) Bazel would try to load
androidx.compose.ui.tooling.preview.ComposeViewAdapter
instead ofandroidx.compose.ui.tooling.ComposeViewAdapter
due toBlazeModuleSystem::getResolvedDependency
unable to resolve dependencies.The logic in getResolvedDependency relies on
MavenArtifactLocator
to do the lookup but the plugin as for today does not have anyMavenArtifactLocator
extensions registered. -
Missing classes in the class path of ModuleClassLoader
ModuleClassLoader
is responsible for initializingComposeViewAdapter
and required to have specific classes in the class path. CurrentlyBlazeClassJarProvider
which is responsible for providing the external libraries jars to the class path is returning nothing for the.workspace
module, the straightforward solution is to include all of the libraries in the workspace module case. -
External libraries resources can't be looked up This is somewhat related to the previous issue in the way that android resources are not available in the class path of
ModuleClassLoader
but in this case the issue is caused because of the existing logic inBlazeAndroidWorkspaceImporter::createAarLibrary
is creating theAarLibrary
models with an empty package name. The solution here is to somehow infer the package name from the actual aar (perhaps reading them from the manifest files?)
I'm more than happy to give it a shot and create the PRs with my proposals it would be great though if someone who is more familiar with the codebase could give a few insights on the solutions I proposed.
I work on the Android Studio for Blaze team, so I'm aware of some of the issues, but we do not have the bandwidth to officially support this for Bazel users. But here are some pointers:
-
MavenArtifactLocator
: Internally at Google, we don't use Maven. So what we've done is introduce this layer of abstraction calledMavenArtifactLocator
. We recognize certain known artifacts, and redirect them to the target where they are checked into source control. For Bazel, I have no idea how different companies are handling it, but one option is to write an ArtifactLocator that picks artifacts from Maven (just like Gradle would do). -
ModuleClassLoader
: Some of the changes we did here only applied to Blaze, so they aren't in the open source Bazel plugin, but the issues are probably minimal. Perhaps the Bazel team may help here. The expectation is that the class loader is supposed to provide the .class file corresponding to any fully qualified class name. The approach we follow internally now is to build deploy jars corresponding to allandroid_binaries
, and use those deploy jars to provide the classes. -
AarLibrary
instances should be created fromBlazeAndroidWorkspaceImporter
with the correct package name. If they aren't, then perhaps there is a Blaze vs Bazel difference.
Even after all of this, there are some more gotchas (mainly around R class resolution). Re: PRs, I think a solution for the MavenArtifactLocator
would be fairly isolated and possible to accept, but the other two are somewhat involved and would need time from someone in the bazel team to review and verify that everything is ok.
@sgowroji would you be able to help triage this one?
@idanakav are you currently using this/is it still working? I cherry picked your branch into the latest release, and I'm getting errors like "Cannot obtain the application ID."
Have a working solution for Dolphin: https://github.com/ergatta/intellij/pull/1