After the <Android Makers talk> about Remote Compo...
# compose
b
After the Android Makers talk about Remote Compose (great one by the way!) I have “conference syndrome” and want to play a bit, but didn’t find a lot of documentation 😅. I'd like to confirm at least one aspect: this blog post (ranks high when googling) implies a document can be created on the server side using the Compose DSL / composable functions - but that’s incorrect, since
remote-creation-compose
is an Android artifact. Right?
b
Yeah that sounds about right. I guess I'd like an example of how to use the
remote-reation-jvm
one. But I suspect it's not fun at all 😉
(I can't imagine writing Compose-like code without Compose)
y
Yeah, androidx doesn't host ComposeMP so the best we can offer is the lower level API. But John shows you can be super productive at that creation level, in fact it usually exposes more operations.
b
Digging a bit more, looks like there's a Kotlin DSL which looks like:
Copy code
RemoteComposeContext(
      width = 640,
      height = 480,
      contentDescription = "test",
      platform = JvmRcPlatformServices(),
    ) {
      root {
        column {
          row {
            text("Hello,")
            text("World!", Modifier.padding(8))
          }
        }
      }
    }
but didn't find an example of how to write a document from that yet
b
ahhhh nice! 👀
well, I managed to draw some things, but
text("test")
fails with
Unknown operation encountered 239
Digging into the Java sources wasn’t very fun I must say 😅 I hope all this can be Kotlinized at some point (can’t Gemini convert it in a minute? 😛)
y
There is a coretext operation in AndroidX profile (V8 or cinnamon bun).
Actually I think I fixed this
Might need very latest alpha? Or it's a different bug?
Are you testing on an embedded player or a widget? If widget, which platform version?
b
I'm using alpha.8. Using embedded player.
y
This change is meant to avoid it being used when not supported. But embedded player with AndroidX profile should support it. https://android-review.googlesource.com/q/I85116b2d85122b549ce27fe254ff82d19d74db81
b
I'm probably doing something wrong. But I'll make a reproducer if that helps.
1
y
From the doc I sent (I was on Eurostar on mobile) you should be able to bump the api version. So you have a choice • Use apiLevel 7 but it shouldn't be using CoreText, just TextLayout. This seems like a bug. • Use AndroidX + apiLevel 8 (CoreDocument.DOCUMENT_API_LEVEL) which should support CoreText
Copy code
val rc = RemoteComposeContextAndroid(
        platform = AndroidxRcPlatformServices(),
        apiLevel = 7,
👀 1
u
Does anyone know if the talk was recorded? Or is it too soon?
b
It was recorded but not published yet
👍 1
I guess there are a few concepts that need to be documented (or maybe they are but didn’t find it): what’s the difference between
RemoteComposeContextAndroid
vs
RemoteComposeContext
, what’s a Profile, what’s
RcPlatformServices
, what’s an API level (I suppose not related to Android API level),
RemoteDocument
vs
CoreDocument
. My POC is a server serving a document (a button 😅) and an Android app showing it on screen. Uncommenting this line triggers the unknown operation error.
y
So the only public API is remote-creation-compose right now. The rest is in some flux but available for testing.
👍 1
b
Ahh I see.
remote-creation got split up into remote-creation-core (Java) and remote-creation (KMP)
So RemoteComposeContextAndroid is in remote-creation (android) and can use Android APIs
Most obvious are Bitmap and Path
A Profile is
/**
* Represent a RemoteCompose *profile*
*
* <p>A *profile* can be set when creating documents and will allow to validate the creation. A
* *profile* encapsulates:
*
* <ul>
*   <li>api level for the operations - the operation *profile*s used (i.e., this plus the api level
*       defines the set of valid operations)
*   <li>a platform services implementation
*   <li>a RemoteComposeWriter instance
* </ul>
*
* A subclass of RemoteComposeWriter can be provided by the *profile*, allowing additional validation
* (e.g. validating parameters for a specific functionality) Additional features will likely be
* represented via *Profile* in the future (set of valid host actions, etc.)
*/
public class *Profile* {
And you can see typical ones public class *RcPlatformProfile*s { /** * Profile for Glance Widgets for Platform 16. * <p> * This will be moved to the glance module when creation APIs are public, before * stable APIs. */ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public static final @NonNull Profile WIDGETS_V6 = new Profile(6, 0, new AndroidxRcPlatformServices(), (creationDisplayInfo, profile, callback) -> new WidgetsProfileWriterV6(creationDisplayInfo, null, profile)); /** * A profile for creating Remote Compose UIs for use with the embedded AndroidX Player. * * <p>It uses the {@link RemoteComposeWriterAndroid} to serialize the UI tree. */ public static final @NonNull Profile ANDROIDX = new Profile(CoreDocument.DOCUMENT_API_LEVEL, RcProfiles.PROFILE_ANDROIDX, new AndroidxRcPlatformServices(), (creationDisplayInfo, profile, callback) -> new RemoteComposeWriterAndroid( creationDisplayInfo, null, profile, callback));
If you pass RcPlatformProfiles.ANDROIDX into RemoteComposeContext, it should fix your issue. But if you can raise a bug I'll make sure it get's fixed, and we update the docs.
I think there are two issues 1. you should use a profile with CoreText support 2. RemoteComposeContext should be using a codepath that checks whether coretext is supported before using it.
b
I think I can't use
RcPlatformProfiles
on my server (JVM) because it's in the android artifact?
y
Ahh, yep. I guess copy and adapt one in your project and use it consistantly.
Again, none of this is currently public API
b
All right 🙂 Well, no worries at all, I see all of this is still early.
Wanted to play a bit with it and I think I'm satisfied for now 🙂
y
I hope your experience with the public APIs in the Compose API would be smoother 🙂
👍 1
u
If I may hijack for a bit. I notice these
RemoteColumn
etc. Does that mean I cannot use my existing design library of `@Composable`s?
y
Correct. You will get errors about wrong applier
An early version supported existing UiCompose composables by recording the canvas calls. But it wasn't a stable approach. So since removed.
u
I see but does it never intend to support them in future, and I'd always need to reimplement my theme/standard components?
y
Shared components are a thing we could build, but would require a lot of effort by a lot of teams other than just RC. Nothing I can promise at this point. And even then, there are different approaches, it's more likely we offer to reuse RC in normal compose.
👍 2