Android 原生的 Compose A2UI 也来了,你还抱着 XML 养老吗?

Andorid Compose 的 A2UI 终于正式落地 AndroidX 了,这个我们在 Flutter 已经聊过很多次了,这次还是官方第一次通过 Compose Renderer 的形态落地到 Android。

也就是 Android 原生也可以接收 A2UI 协议,然后通过 Agent 描述交互界面,再渲染成 Native Compose Component,同时执行 Agent 生成的逻辑代码。

可能很多人说,这玩意浪费 Token 又慢,有什么用?这个其实 Flutter 的时候就讲过了:

  • 首先它一些 UI 可以根据用户数据,提前在后端生成,在使用之前就匹配好,也可以 Cache,真正用的时候直接就可以渲染出来就行
  • 其次还有 Client-Side Functions ,也就是逻辑也可以根据 UI 一起绑定,动态生成

类似于 Catalog 可以同时持有 CatalogItem 和 ClientFunction,生成 capabilities 时,每个 function 会暴露 name、description、parameters 和 returnType,然后生成完整 Catalog Schema 时,会把每个函数变成一个合法的 FunctionCall schema。

所以实际上在 A2UI 场景,模型其实拥有的是一张"能力菜单",它知道有哪些函数,知道函数需要什么参数,也知道返回值是什么,但真正的实现还是在 App 手里,具体实现模型不关心,它只关心需要组合成什么UI ,UI 需要加载什么逻辑。

然后现在这套逻辑可以用在 Android Compose 上面了,官方 Compose Renderer 已经有协议解析、Schema Validation、Surface State、Compose Runtime 和 Component Catalog。

Agent 发来的结构化 UI 更新进入 A2uiMessageProcessor,对应 Surface 更新后,Compose 只重组真正变化的组件,而且它还支持反向事件,所以用户操作原生 Button、Picker 后,结果可以沿着 A2UI Client Event 回到 Agent。

而这里 Jetpacker 源码里的核心初始化其实很简单,初始化之后,界面会直接消费这些 activeSurfaces,交给 A2uiSurface 渲染。

ini 复制代码
private val messageProcessor = A2uiMessageProcessor(
    catalogs = listOf(bookingAssistantCatalog())
)
​
val activeSurfaces = messageProcessor.activeSurfaces

不过目前的 Jetpacker 还没有做到完全的「ADK Agent 直接吐标准 A2UI Tree」 ,目前看 BookingAssistantViewModel.kt,是通过 Cloud Run 后端 SSE 发来的是 ADK Event,其中还夹着类似 time_selection、seat_map、ticket_selection 这样的业务语义,然后 Android 的 parseAndApplyEvent() 再把它们转换成 InteractiveOptionPicker、SeatSelectionPicker、BookingConfirmation 之类的 A2uiComponentPayload :

所以 A2UI 暂时只是解决了客户端的结构化 UI Runtime,但 Jetpacker 这个 Sample 里,Agent Runtime 与 A2UI 之间还存在一层业务 Adapter。

然后就和之前聊的 Flutter A2UI 一样,生成的权限会被 Component Catalog 卡得很死, App 开发者先定义一个 Component Catalog,Agent 只能用这里声明过的 Component、Property 和 Client Function。

Android 官方把 Catalog 叫做 formal contract,比如你的 App 可以开放 Text、Card、Button,也可以像 Jetpacker 一样增加自己的 SeatSelectionPicker、BookingStatus、BookingConfirmation,然后 Agent 能决定:

"现在需要一个 SeatSelectionPicker,标题是什么、座位选项是什么"。

之后真正的 Compose 实现、主题、交互能力能说客户端提供,而且 AndroidX 会在 Payload 进入 Compose UI Tree 前做 Schema Validation,如果 Agent 幻觉出一个不存在的 Component,会变成 Error State 并回报给 Agent。

比如 Jetpacker 目前同时有两段航班、一个酒店、一个博物馆和一个餐厅:

  • Android 把这些行程发给 Cloud Run 上的 Python ADK Backend
  • 然后服务端的 ItineraryOrchestratorAgent 先按类型拆成 Flight、Hotel、Museum、Restaurant 几组
  • 然后塞进 ADK 的 ParallelAgent每一组内部如果有多个项目,还可以继续创建多个子 Agent 并行跑

在这个过程里,Agent 先生成一个起飞时间,发送 time_selection,随后直接停在:

scss 复制代码
await session.pause_events[title].wait()

Android 收到 SSE 后把这个状态变成 A2UI 的 InteractiveOptionPicker,然后用户在手机上点 Confirm,客户端事件里带着具体 agentId 和选择结果回到 /respond,服务端把结果写进 Session,再调用对应的:

scss 复制代码
session.pause_events[pause_key].set()

再之后刚才被挂起的那个 Flight Agent 才继续执行下一步 Seat Selection,酒店会停下来等待 Reservation Confirmation,博物馆等待 Ticket Confirmation,餐厅等待人数选择,而其余没有被用户卡住的 Agent 会继续执行:

也就是用户可以在多个动态 A2UI 之间并行操作,并行处理,这种能力其实在 AI 手机场景上还是有些用的,至少能可以同步处理多个事件,然后通过可交互 UI 的方式来让用户决策,不然每次都让用户看一堆文字的体验去试试不咋地:

所以 A2UI 也是 Tibo 说的场景之一,也许未来代码根本不需要每次发版,只需要根据场景动态生成就好了:

相关推荐
庄园特聘拆椅狂魔1 小时前
从连连看到粒子消散——前端小游戏与视觉特效的技术选型
前端
程序媛_1 小时前
【JMeter】准备token文件
android·jmeter
JudithHuang1 小时前
React 常用 Hooks
前端·react.js·前端框架
维克兜率天1 小时前
【维克】弹性策略:用“乖离率“捕捉超跌反弹
android·开发语言·python·深度学习·kotlin·量化
古法安卓2 小时前
Android-Ext4文件系统问题排查
android·java·android studio
sycmancia2 小时前
Qml——Window元素使用
前端
每天都好困2 小时前
03 AR 投影与误差修正:把地图上的点贴到视频画面上
前端
每天都好困2 小时前
04 地图图层封装:像管理 Photoshop 图层一样管理地图元素
前端
去伪存真3 小时前
构建你的第一个 DevOps AI Agent:自动化捕获、分析并修复 CI 故障
前端·agent