应用基础知识

使用 Remote Compose 为互动式界面提供支持

扬声器

  • Nicolas Roard

    资深软件工程师

  • John Hoford

    开发者

  • John Zoeller

    开发者关系工程师

关于

演讲简介

Remote Compose 引入了一种新方法,可将富有表现力的互动式界面投射到微件等远程界面上。通过将布局序列化为紧凑的二进制载荷,RemoteCompose 将界面与主机执行解耦,从而带来显著优势。

其主要优势包括:边缘交互性,通过在远程设备上本地执行来实现高性能渲染;平滑扩缩,通过远程端组件评估,使界面能够在各种设备规格之间重排;以及统一的开发者工作流程,通过熟悉的 Jetpack Compose API 消除对平台专用远程界面框架的需求。

本场讲座将详细介绍这些优势,并提供实际应用示例,包括现代 Wear OS 微件和 Runkeeper 中一目了然的 Wear 锻炼跟踪器体验。

摘要

  • Remote Compose 会将界面打包成紧凑的二进制文档,而不是跨进程边界发送应用或屏幕副本。
  • 开发者可以使用 Compose API 或 JSON 创建文档。Android Studio 会在您编写可组合项时提供实时预览。
  • 加载的文档会直接在播放器上自行运行。它们会处理调整大小和触摸等事件,而无需往返于其创建者。
  • 组件模板和文档压缩等内置优化功能可将载荷缩减至几千字节。
  • Jetpack Glance 会为启动器 widget 和 Wear OS widget 发出 Remote Compose 文档。这会将界面与应用执行分离开来,以节省电量。

资源

Gemini Notebook

主题

  • remote-compose
  • jetpack-compose
  • android-widgets
  • wear-os
  • ui-framework

转写文稿

远程 surface 简介和概览

  • 大家好,

  • 大家好,我叫 Nicolas Roard,是 Remote Compose 项目的技术主管。

  • 我是 John Hoford。

  • 我是 Remote Compose 团队的开发者。

  • 我叫 John Zoeller,负责 Wear OS 的开发者关系。

  • 好了,我们开始吧。

  • 首先,我将简要介绍一下我们试图通过 Remote Compose 解决的问题。

  • 通常,当您谈论或思考 Android 上的界面时,您会认为界面是应用和应用进程的一部分,对吧?

  • 在很多不同的情况下,您可能需要将界面打包并发送到其他位置,例如远程界面。

  • 我们所说的远程界面,其实就像这些示例一样,比如表盘样式、微件,甚至可以是您自己的应用或其他应用,对吧?

  • 因此,这些基本上都是远程界面的示例。

  • 因此,在其他地方(可能是您的应用,也可能是服务器),有其他地方知道要向该远程界面发送什么内容。

  • 还有…

  • 我的音箱呢?

  • 这两者之间基本上存在距离。

  • 这种距离可以是实际距离,也可以是网络连接,对吧?

  • 也可能只是进程边界。

  • 您可能使用的是同一部设备。

  • 但无论是什么,都有代价。

  • 您能想到的最简单的传输界面的方法就是截屏,然后发送。

  • 但问题是,这种方式不够快,对吧?

  • 因此,我们使用 Remote Compose 的做法是发送一个代表该界面的文档。

  • 请记住,小团队有很多优势。

  • 这很重要。

  • 我们从您发送的第一个像素中看到了这一点,但实际上,您想在该平台上进行的任何更新都是如此,对吧?

  • 您已完成往返。

  • 这样,您就可以在远程界面上获得一些信息,例如事件、点击、轻触。

  • 您必须联系创建者,获取新版本。

  • 这可不太好。

  • 因此,在许多方面,这正是我们试图通过 Remote Compose 解决的问题。

Remote Compose 架构和文档结构

  • 我们看到了文档的发送过程。

  • 除了文档之外,还有几个非常重要的领域。

  • 一个是您如何创建该文档。

  • 第二点是游戏玩法。

  • 我提到过,我们正在创建一份文档。

  • 我们不会发送屏幕副本,也不会发送应用。

  • 因此,我们提供了三种不同的方式来帮助您创建该文档。

  • 一是 Compose API,二是过程式 Kotlin API (KMP),三是 JSON 格式。

  • 它们都会发出相同的字节。

  • 因此,我们提供了一套工具来创建这些文档,借助 Compose API,我们实际上可以利用 Android Studio 中的现有工具。

  • 例如,您可以使用预览功能直接在 IDE 中实时查看正在开发的内容。

  • 但我们也在开发一些强大的新工具,例如文档检查器。

  • 我们来快速了解一下该文档的实际内容。

  • 它本质上是一个以紧凑二进制表示形式编码的操作列表,这些操作描述了一个可以发送到该远程界面的独立界面。

  • 因此,这些文档的一个非常重要的特征是它们很小。

  • 在我们看来,小巧是件好事。

  • 所以通常只有几 KB,对吧?

  • 但即使是更复杂的界面,比如具有高度自适应布局的界面,其大小也只有几十 KB,对吧?

  • 我们会将所有素材资源打包到该文档中。

  • 因此,仔细想想,唯一能真正占用文档空间的就是开始打包位图。

  • 请注意这一点。

  • 毕竟,这就是我们发送文档而不是屏幕截图的全部原因。

  • 当我们谈到小巧和重要时,不仅仅是指通信。

  • 这是 Remote Compose 背后理念的一个核心极端情况。

  • 正如我们所见,它显然会影响在屏幕上显示第一个像素所需的时间,但糟糕,抱歉。

  • 这也意味着,在表面容量相同的情况下,我们可以使用比其他方式更多的文档,同时仍能保持高效。

  • 我们会在支持微件时利用这一点。

  • 播放器本身往往也很小,依赖项非常少。

  • 由于它们体积小且依赖项少,因此我们可以将 Remote Compose 文档的播放范围扩展到更多地方。

  • 正如您将看到的,这对于受限平台尤为重要。

  • 我讲了很多关于传输和距离的内容,但 Remote Compose 本身并不真正处理传输。

  • 这取决于您。

  • 我们所做的就是将所有这些内容打包到一个字节缓冲区中,然后您可以使用适当的方法将其发送到远程界面。

  • 对于微件,我们为您提供了一个连接器。

  • 但一般来说,请记住,您负责传输。

  • 玩家收到该文档后,无论您通过何种方式发送,都可以提取操作列表并将其转换为绘制命令、布局树、表达式,所有这些结合在一起,可以打造非常丰富的用户体验。

  • 因此,请务必注意,由于您可以自行决定如何传输文档,因此您可以在许多场景中将 Remote Compose 作为工具重复使用,其中一些场景甚至可能是我们未曾想到的,对吧?

  • 文档由播放器加载后,会自行运行。

  • 这就是整个想法。

  • 我们希望文档能够创建某种程度上自主的界面,无需返回到创建者,对吧?

  • 所有这些功能,包括调整大小、滚动、触摸事件、决定显示或隐藏组件、动画、一些触摸事件和一些触摸处理,都可以在文档中完成,而无需返回播放器。

  • 有时,如果您需要返回到创建阶段,可以请求执行操作,例如“请给我一份新文档”。

  • 我们主要通过 Remote Compose 中的 AndroidX 库提供三个官方播放器。

  • 一个是 Compose 播放器,因此您可以在 Compose 应用中使用它。

  • 如果您仍在使用 View,我们还提供 View 播放器。

  • 此外,我们还提供了一个 RemoteViews 实现,该实现自 API 36 起在 Android 平台中提供,可让您使用 Remote Compose 创建在启动器上运行的 Android widget。

  • 如果您感兴趣,我们还提供了一些实验性播放器,包括在 Skia 上运行的 C++ 播放器、TypeScript 播放器,甚至还有 Compose Multiplatform 播放器。

  • 因此,其理念是,您使用的技术基本上可以用于在许多不同的平台和平台上进行渲染。

  • 总而言之,我提到的距离感依然存在,但我们正在努力让它只在真正重要的时候才发挥作用。

  • 没错

渲染功能、组件和互动

  • 接下来,我们来简单介绍一下 Remote Compose 文档中提供的功能。

  • 因此,它的基础是一个 Canvas,它具有 Android Canvas 的所有功能。

  • 但其中包含一些额外的 API。

  • 但其中一个特别之处在于,Android Canvas 中的所有浮点数都可以替换为表达式。

  • 这样,您就可以实现动画、动态缩放和灵活布局,如您在此处所见。

  • 它有很多不同的用途。

  • 详细了解表达式。

  • 您可以使用丰富的运算符,包括常规数学、三角函数、数组访问、样条插值等。

  • 其中一个很酷的功能是,任何发生变化的值都可以添加动画效果,因此您可以为任何值的状态变化添加动画效果。

  • 在您看到的这个特定绘图中,每个摆锤都会选择一种不同的动画类型,所有这些动画类型都可以在 Remote Compose 中使用。

  • 除此之外,我们还有基本组件、Compose 内容,以及您熟悉的内容。

  • 它会生成非常熟悉的 API、Box、Row、Column 等。

  • 但除此之外,我们还有自适应组件。

  • 这样做的好处之一是,由于您当时无法控制文档,因此这些对象可以处理消失、出现、消失、因调整大小而返回等情况,而无需返回文档源。

  • 除此之外,我们还有组件动画。

  • 所有更改都可以添加动画效果,因此,如果某个元素消失,您可以为其添加动画效果。

  • 您还可以编写自己的自定义动画。

  • 在这个例子中,您可以看到其中一些使用了着色器等各种技术。

  • 我们还能实现的一点是,让用户在观看时进行互动,所以这不仅仅是漂亮的图片。

  • 您可以点击内容、触发触摸事件、滚动页面等。

  • 无障碍功能同样重要,因此所有无障碍功能 API 都在这里。

  • 您在这里看到的是,我正在构建一个完整的秒表,上面有一些有趣的界面,所有这些都是在播放器端发生的。

  • 所有这些都在文档中。

  • 您看到的所有内容,都无需返回服务器。

  • 现在,如果您在应用中构建了它,那么在这种情况下,蓝色部分是应用,黑色部分是 Remote Compose 文档。

  • 您实际上可以在两者之间进行互动。

  • 在这里,我正在递增值,您可以看到应用(我们称之为主机)正在接收这些值,我还可以移动滑块,这会更改文档中的值。

  • 因此,我可以双向操作。

使用 Compose API 和表达式构建界面

  • 接下来,我们来深入了解如何创建这些文档。

  • 实际上有三个 API:Compose、Kotlin 和 JSON。

  • Compose API,您大概知道它是什么样的。

  • 它有一些变化,我们将详细介绍。

  • Kotlin API 非常注重过程。

  • 文档中基本上是一条指令,所以基本上是一对一。

  • JSON 是一种 JSON 语法,您可以使用我们的转换器将其转换为 Remote Compose。

  • 如果您正在使用 LLM,它也很有用,因为 LLM 能够读取和写入文档。

  • 现在,我们来实际进入 Compose 并构建一些内容。

  • 在本例中,您会看到它是一个可组合项,也是一个远程可组合项。

  • 我们有一个画布,不是画布,而是远程画布和远程修饰符,但修饰符本身是一样的,就是您熟悉和喜爱的那些。

  • 现在,其中的所有命令实际上都会在执行过程中生成远程命令 Remote Compose 文档命令。

  • 在本例中,我们绘制了一个圆圈,然后添加了一些浮点数和表达式,并在这些表达式中使用了时间。

  • 当我在动画中开启它时,请注意,这是 Android Studio 的实时预览,它实际上会为您实时运行。

  • 您可以在此处看到这些表达式。

  • 我们来稍微了解一下它的具体内容和运作方式。

  • 在左侧,您会看到一个类似于电子表格的界面。

  • 这是一个浮点值表格。

  • 它还提供依赖项树,让您清楚了解各个组件之间的关联。

  • 每当发生变化时,其依赖项都会被标记为脏数据,以便进行清理和调整。

  • 在运行过程中,它会清理所有依赖项,并仅评估发生变化的依赖项。

  • 因此,这种方法非常高效。假设某个对象(例如大小)发生变化,那么该依赖项也会发生变化,并且必须反映这种变化。

  • 这是一种非常高效的计算方式,因为您是从上到下,而且效率非常高。

  • 我们稍微扩展一下这个时钟,展示一下我们可以构建一些真实的东西,稍微真实一点的东西。

  • 在本例中,我们要做的是在边缘添加一些刻度线,您会看到一些 for 循环,因此您可以在本地和右侧进行 for 循环。

  • 然后,我们添加一些时针和分针,接着添加秒针,最后用几个不同的按钮来完成它,这样我们就得到了一个实时时钟。

  • 你看,它确实显示了时间。

  • 另一个有趣之处在于,您可以用 JSON 编写相同的内容,如果是 JSON 格式,您可以轻松地与 LLM 互动,比如对它说“将分针改为绿色”,它就会理解您的意思。

  • 所以,这样非常好。

  • 好的。

开发者工具和文档优化

  • 是的。

  • 希望这能让您对 Remote Compose 的功能有所了解。

  • 接下来,我将简要介绍我们为开发者提供的支持。

  • 我提到过,这些主要是 AndroidX 库,因此 DAC 上的所有内容,您都知道在哪里可以找到。

  • 您将获得最新版本、文档等所有内容。

  • 和往常一样,John 演示了我们可以在 Android Studio 中执行的操作。

  • 我认为最棒的功能是实时预览,它能显著缩短开发时间。

  • 我们还在努力为该格式制定一种实际的公开开放规范,对吧?

  • 我们并不是要隐藏什么,它就在那里。

  • 您可以了解它的运作方式,以及它的实际构建和编码方式。

  • 您在应用中经常使用的一种资源是动画矢量可绘制对象,显然,这非常方便。

  • 还记得我提到的位图吗?

  • 我们非常希望您发送矢量图,而不是位图,对吧?

  • 因此,我们正在开发一些工具,帮助您将 Lottie(或其他格式)转换为 RemoteCompose 组件,以便在 RemoteCompose 文件中使用。

  • 我之前提到过,我们还在开发其他工具,特别是针对文档的实时检查器,因为拥有创建文档的开发者体验是一回事,而能够检查创建结果又是另一回事。

  • 在本例中,该对象是一个文档。

  • 因此,我们先来快速预览一下我们正在开发的工具。

  • 它是一个 RemoteCompose 文档检查器,顾名思义,它可以让您检查文档,并应用多种实用的工具和可视化功能。

  • 一个很好的例子是,您可以打开一个文档,然后逐步执行文档中的不同操作,以便更好地了解所有内容是如何联系在一起的。

  • 但我们还有其他工具。

  • 例如,我非常喜欢这个功能,它可以立即以不同的密度和尺寸直观呈现您的文档,这样您就可以非常快速地查看您正在构建的内容是否能够很好地适应不同的尺寸变化。

  • 我们最近还在开发一个功能非常全面的布局检查器,它具备您在 Android Studio 中习惯使用的布局检查功能,但在这里,它适用于操作和文档,对吧?

  • 在 3D 方面,我们还可以更进一步。

  • 我之前提到过,希望现在我已经说服您,小巧也是一种优势。

  • 这很重要。

  • 我们确实希望文档较小。

  • 这能帮到所有人。

  • 请执行此操作。

  • 那么,我们能做些什么呢?

  • 我们来看一个常见的界面示例,好吗?

  • 比如,您有一堆行。

  • 行本身包含名称、小图表,可能还有一个按钮。

  • 这很常见。

  • 该界面的尺寸已经非常小了。

  • 我们说的是大约 25 kB,但 RemoteCompose 中有各种功能,实际上可以帮助您将其做得更小。

  • 我们来逐一了解一下。

  • 我们首先会做的一件事是,如果您发送相同的字符串,我们会注意到这一点,并免费为您处理。

  • 通过指向同一字符串,我们可以节省一些字节。

  • 但我们提供了更多内容,例如循环。

  • 在这里,我使用这个循环操作来绘制我的小图,对吧?

  • 这样可以节省更多字节。

  • 我们也有函数。

  • 因此,您可以创建一个函数,在这里,我再次为该图表创建了一个函数,然后我就可以多次调用该图表。

  • 同样,这也会节省一些字节。

  • 对于组件,我们有模板,对吧?

  • 与函数类似,但更侧重于组件,对吧?

  • 因此,我只需使用正确的参数调用该模板,就可以替换所有这些不同的组件和行,从而节省大量文档空间。

  • 最后,我们还支持对文档进行压缩。

  • 一般来说,通过这种方式,您可以节省大约一半的文档大小。

  • 有趣的是,文档的标题有点特别。

  • 我们不会对其进行压缩。

  • 如果您想快速筛选大量文档而无需解压缩,这会非常方便。

  • 总之,文档本身就很小,但您也可以让它们变得更小。

  • 通过这个小例子,您可以看到,将模型大小缩减一个数量级是多么容易,而小巧本身就是一项优势。

微件和 Wear OS 中的 Remote Compose

  • 我介绍了 Android 平台中的微件,特别是启动器微件。

  • 接下来,我们来简单介绍一下我们正在做的工作以及已经推出的功能。

  • 因此,我们首先可以做的是,在 RemoteCompose 中完全复制一个现有 widget(例如那个时钟),它在 RemoteCompose 中的行为基本上是一样的。

  • 但我们还能做得更好,对吧?

  • 因此,如果您想打造更具自适应性的界面,让微件能够调整大小并正确呈现动画,现在就可以实现,对吧?

  • 因为我们有合适的基元来实现这一点,而使用 RemoteView 则无法做到。

  • 基本上,我们为您提供了更大的灵活性和更强大的功能。

  • 说到功能强大,这里有一个简单的例子,展示了您可以做的一些疯狂的事情,对吧?

  • 此示例展示了如何在微件中显示完整游戏。

  • 我会指出该微件的实际大小。

  • 我们说的是 4 KB。

  • 我提到过,传输不是我们在 Remote Compose 中直接处理的内容。

  • 不过,对于微件,我们确实提供了一个 RemoteCompose 微件连接器类,让您可以非常轻松地获取文档并将其发送到启动器。

  • 也就是说,如果您已经有 widget,我们建议您继续使用 Glance,因为最新版本的 Glance 会自动提供一个后端,以便在平台上发出 Remote Compose。

  • 现在,我们来谈谈 Wear OS。

  • 谢谢 Nico。

  • 大家好!

  • 我是 John Zoeller。

  • 今天我想为你介绍一下 Wear OS。

  • 我为这次演讲写了大约 30 个笑话,但我把这些笑话都讲给我妈妈听了,她说如果我讲了其中任何一个,我都会被解雇。

  • 因此,我将跳过该部分,直接进行演示。

  • 接下来,我们来聊聊 Remote Compose 及其在 Wear OS 上的优势。

  • 首先,我们将介绍全新的 Wear OS 锻炼跟踪器。

  • 我们使用 Remote Compose 构建了这款应用,并且深知为 Wear 构建功能齐全、高品质的锻炼跟踪器非常困难。

  • 这需要一些时间。

  • 因此,我们为你做了这件事,并加入了一些非常棒的新型现代锻炼功能,例如实时指标和媒体控制功能。

  • 得益于 Remote Compose,我们能够将界面与所有执行操作分离开来,因此它能够非常高效地运行,并且有助于避免耗尽用户的电池电量。

  • 如果没有 Remote Compose,而只是使用普通 Compose,我们就无法在屏幕上实时刷新指标。

  • 实际上,这需要一分钟的时间,因为您必须在氛围模式下唤醒手表,才能显示指标。

  • 因此,这是一个巨大的优势。

  • 实际上,信不信由你,这是一个 GIF。

  • 这不是图片。

  • 我知道它还没有变化,但大约 45 秒后,当系统进行下一次指标更新时,它就会发生变化。

  • 但这就是 Remote Compose 的优势。

  • 您知道吗?

  • Wear Workout Tracker 实际上已经上线。

  • ASICS Runkeeper 应用就是使用该技术构建的新应用,您现在就可以点击此链接加入其公开 Beta 版测试,亲自体验一下。

  • 接下来,我们来看看 Wear OS 微件。

  • 这是 Remote Compose 的另一个绝佳应用示例。

  • 这些库取代了旧版 ProtoLayout Tiles 库,因此您无需再为不同设备支持两种不同类型的界面框架。

  • 您可以使用 Remote Compose 完成所有这些操作。

  • 由于 Wear OS 上的微件属于 Jetpack Glance,因此它们也是统一的 Android 生态系统的一部分。

  • 好的。作为此生态系统的一部分,RemoteCompose 微件的界面与任何特定应用进程完全解耦,因此可以使用与 Android 堆栈其余部分相同的技术,在 Wear OS 设备上安全地进行序列化和渲染。

  • Remote Compose 还为微件带来了现代图形和自适应布局,同时非常高效且省电。

  • 在 Wear OS 7 中,硬件制造商已经开始采用垂直滚动托盘。

  • 这是 Samsung Galaxy Watch,您可以看到微件在托盘中垂直滚动。

  • 如需详细了解如何将卡片迁移到微件,请访问此链接。

  • 在依赖横向轮播界面显示卡片的旧款设备上,微件会自动显示为全屏卡片。

  • 此外,它们还完全向后兼容 Wear OS 4。

  • 此外,您还可以通过此链接详细了解向后兼容性。

  • 此外,还有一些其他合作伙伴也已经采用了微件。

  • 您可以查看一下。

  • 我的分享到此结束。

  • 是的,Nico,请继续。

  • 谢谢。

后续步骤和收尾

  • 好了

  • 以上就是我们今天分享的全部内容。

  • 我们回顾了 Remote Compose 的一些功能。

  • 还有一些我们没有讨论过的。

  • 这是一个非常丰富的框架。

  • 建议您查看现有文档和即将发布的文档。

  • 我们的目标是打造一个未来,让您能够真正使用 Remote Compose 来应对所有这些不同的远程界面。

  • 您已经看到了一些,比如 Wear、微件。

  • 但还有更多精彩内容即将推出。

  • 我还想说,这是一个持续进行的项目。

  • 该功能正在积极开发中。

  • 我们,你知道,我们都是公开开发这些内容的。

  • 您可以看到我们正在做什么。

  • 不过,我想说的是,我们非常希望听到开发者的反馈,对吧?

  • 我们正在为您打造这样的产品。

  • 因此,如果您有其他想法或发现有任何缺失,请告诉我们。

  • 我们非常高兴收到您的反馈。

  • 最后,我想说的是,您刚才看到的整个演示(包括动画)都是在 Remote Compose 中完成的。