概述
从 Node.js 脚本展示交互式 Android 原生界面。
展示页面
从 supernode 导入 app。app.show({ views }) 打开原生页面,返回 Promise<void>;用户关闭页面且 effects 清理完成后,Promise 返回,await 后的代码继续执行。后续调用可以再次打开页面。
将示例保存为 main.tsx,采用 View 中的 JSX 配置。
import { app } from "supernode";
import { Column, Text, TextField, useState } from "supernode/app";
function Profile() {
const [name, setName] = useState("SuperNode");
return (
<Column spacing={12}>
<Text fontSize={24}>你好,{name}</Text>
<TextField value={name} placeholder="姓名" onValueChange={setName} />
</Column>
);
}
await app.show({ views: <Profile /> });
console.log("页面已关闭,脚本继续执行。");页面由组件构成,用 Modifier 布局与装饰,用 Hooks 与 Context 管理状态,都从 supernode/app 导入。
API 与执行环境
| API | 行为 |
|---|---|
app.show({ views: ViewChild }): Promise<void> | 展示原生页面,等待页面关闭。 |
views | 视图、函数组件、数组、文本、数字或空子节点,详见 View。 |
在 SuperNode 内运行脚本,由宿主提供 RPC 连接。每个 Node 进程可持有一个 App 会话;同时调用第二次 app.show 会报错,顺序调用受支持。Widget 执行环境调用 app.show 会报错。
SDK 将进程工作目录发送给宿主。Image 的相对路径以该目录为基准,同时支持绝对路径、file: URL、HTTP(S)、图片 data URL 和内置 Pika 资源名称。
更新与生命周期
函数组件通过组件身份和 key 保留 Hook 状态。TextField.onValueChange 接收最新字符串,状态变化会增量更新原生界面。稳定的 key 可以在同级组件移动时保留状态。
useEffect 在原生页面挂载后执行。依赖变化时,先清理上一次 effect,再运行新的 effect。关闭页面会清理 effects 和事件处理器;通过同步 cleanup 函数释放定时器或订阅。
旋转屏幕后重新绑定现有会话。返回键与顶部关闭按钮触发清理,宿主最多等待两秒确认。页面空闲时连接持续保留;Node 进程停止或连接断开会释放原生页面。
错误处理
在 await app.show(...) 外使用 try/catch。无效视图、挂载或提交超时、事件处理异常、cleanup 异常和连接中断都会使 Promise 拒绝。原生异常写入宿主日志;修复所报告的问题后再打开新会话。
App 页面跟随系统主题。脚本提供的文案由作者按受众进行本地化;SuperNode 的页面控件提供中英文。