Jetpack Compose��� on the Desktop
The Awesome Android newsletter���s issue #201
pointed out a very interesting Gerrit entry related to Jetpack Compose, hinting
at a future desktop offering. This possibility is something that I have been
tracking for a few months now, so let���s explore what may be going on here.
Expecting Actual Code
When I was poring over the early dev builds of Jetpack Compose, I noticed
that some elements had commented-out expect and actual keywords. For example,
Canvas.kt
had commented-out expect keywords and
AndroidCanvas.kt
had commented-out actual keywords.
Those keywords are tied to Kotlin/Multiplatform (KMP for short).
In KMP, you have Kotlin code that can run across all platforms (Kotlin/Common).
That code can expect an API that, for any given platform, something else will supply
the actual implementation of that API. For example, you can have common Kotlin code
that will expect Android and iOS modules to implement the actual version of the expected
API, using platform-specific stuff to do so. This is a bit reminiscent of how your
main/ source set in an Android app can ���expect��� that each of your product flavors
have an ���actual��� implementation of some class (e.g., a strategy pattern implementation
tied to that flavor).
Since the keywords are commented out, we do not really need a KMP setup to be
able to build or use Compose. And there are fairly few occurrences of these
commented-out keywords, so this may have been just a form of documentation,
leveraging KMP keywords for showing the relationship between functions.
But, somebody was thinking about Compose on multiple platforms, at least to some level.
Android as API
We often say that our code depends upon Android. However, much of the time,
that is really shorthand for ���our code depends upon Android APIs���. We use android
classes and expect them to do what we want them to do. Exactly what those
implementations are and how they accomplish their aims usually is beyond what we
really care about as app developers.
As a result, as long as we satisfy the symbols that we reference and that the
compiler needs, exactly what sits behind those symbols is immaterial, so long as
our code works.
Android developers take advantage of that on a daily basis:
Your compileSdkVersion is used to identify a JAR containing all the public
symbols from the Android SDK. But the actual implementation of all the Java
methods is simply throw new RuntimeException("Stub!"). The real implementation
of Android is added to our classpath at runtime; the android.jar that we compile
against is not packaged in our APKs.
Robolectric, in the end, is an implementation of a slice of the Android SDK that
does not have any Android ties. Robolectric���s implementation gets used in unit
tests that run on the JVM, not on Android, allowing us to test a bit more of our
code than we might otherwise, while also allowing us to avoid having to roll our
own mocks of those android classes.
What That Gerrit Entry Shows
The main Gerrit link
from the Awesome Android newsletter represents a KMP project, targeting the JVM desktop.
In there, desktopMain/ is a source set for code that will be used for desktop apps.
And in that source set, we see class names that look an awful lot like a subset
of the Android SDK, such as android.content.Context and android.view.View.
The implementations of those classes look nothing like Android. For one, they are all
in Kotlin, and last I checked, the AOSP framework classes are still in Java.
And those classes implement a tiny subset of the real framework APIs. Right now, the
desktopMain/ implementation of Context, for example, is 43 lines of code���
including the copyright header comment. There are individual methods in the
real Context class that are longer than that.
The objective appears to be to satisfy the compiler to allow Compose code to build
an Android app, with class and function implementations that use desktop Java instead of Android.
The actual UI is rendered by a SkiaWindow, which relies on JetBrains��� Skija project,
which offers Skia bindings for Java. Skia is an open source
2D graphics library, one that powers rendering in Android, Chrome OS, and in browsers
like Chrome and Firefox.
So, at least at an experimental level, Google appears to be working on getting
Jetpack Compose to support desktop apps, as well as Android apps.
Implementing ���fake��� Android framework classes may be somewhat of a stop-gap.
If Google elects to take Jetpack Compose more fully into KMP, uncommenting
those expect and actual keywords and expanding upon them, then the desktop code would switch
to providing the actual API that Compose is trying to expect.
Of course, right now we have no idea if Google will ever bring this to fruition.
For all we know, this is just an experiment, one that will never see the light of
day (beyond blog posts like this one). We know that it is actively being worked on ���
one of the developers uploaded a new patchset while I was writing this post.
Regardless, implementing something like this is
likely to happen. I have seen other developers start to poke at this sort of thing,
and I considered doing it myself. It���s possible that all of those efforts will come
to naught as well, but there���s a decent chance that somebody will succeed.
If Jetpack
Compose becomes Google���s recommended UI approach for Android, having the ability to
also develop desktop apps from much of the same code base is a nice value-add, at minimum���
and possibly much more.


