AppService

# AppService

AppService 是 AutumnBox 宿主中 App(Tab 页面)的注册表。所有通过 defineApp()context.registerApp() 注册的 App 都由它统一管理。插件可以通过它查询已注册的 App 列表、按插件过滤 App、判断某个 App 属于哪个插件,以及在运行时动态注册和注销 App。

# 获取方式

import { useService, useServiceState } from '@autumnbox/sdk/hooks';
import { AppService } from '@autumnbox/sdk/hooks';

// React 组件中
const appService = useService(AppService);

// pluginMain 或非 React 环境中
const appService = context.getService(AppService);

# API 一览

方法 / 属性 签名 说明
apps readonly apps: IReadonlyState<readonly AutumnApp[]> 响应式的已注册 App 列表
register register({ app, pluginPackageName }): void 注册一个 App
unregister unregister(appId: string): void 按 ID 注销一个 App
unregisterByPluginPackageName unregisterByPluginPackageName(pluginPackageName: string): void 注销某个插件的所有 App
getApp getApp(id: string): AutumnApp \| undefined 按 ID 查找 App
getAppsByPluginPackageName getAppsByPluginPackageName(pluginPackageName: string): AutumnApp[] 获取某个插件注册的所有 App
getPluginPackageName getPluginPackageName(appId: string): string \| undefined 查询 App 所属插件

# 订阅 App 列表

apps 是一个响应式的 IReadonlyState,当有新 App 注册或注销时自动通知订阅者。配合 useServiceState 使用时,列表变化会自动触发 React 重渲染:

import { useService, useServiceState } from '@autumnbox/sdk/hooks';
import { AppService } from '@autumnbox/sdk/hooks';

const AppCounter: React.FC = () => {
  const appService = useService(AppService);
  const [apps] = useServiceState(appService.apps);

  return <span>当前已注册 {apps.length} 个应用</span>;
};

# 查询 App

# 按 ID 查找

const appService = useService(AppService);

const shellApp = appService.getApp('shell');
if (shellApp) {
  console.log('找到应用:', shellApp.name);
}

# 查看 App 归属

const pluginName = appService.getPluginPackageName('shell');
// → 'autumnbox.main-plugin'

# 按插件过滤

getAppsByPluginPackageName 返回某个插件注册的所有 App,适合构建"查看此插件提供的功能"类 UI:

const appService = useService(AppService);

const mainApps = appService.getAppsByPluginPackageName('autumnbox.main-plugin');
console.log('main-plugin 注册了', mainApps.length, '个 App');
for (const app of mainApps) {
  console.log(`  - ${app.id}: ${app.name}`);
}

# 实战示例:自定义应用启动器

构建一个网格布局的应用启动器,配合 NavigationService 实现点击打开:

import { useService, useServiceState } from '@autumnbox/sdk/hooks';
import { AppService, NavigationService } from '@autumnbox/sdk/hooks';
import { Card, Row, Col, Typography } from 'antd';

const AppLauncher: React.FC = () => {
  const appService = useService(AppService);
  const nav = useService(NavigationService);
  const [apps] = useServiceState(appService.apps);

  return (
    <Row gutter={[16, 16]}>
      {apps.map((app) => (
        <Col key={app.id} span={6}>
          <Card
            hoverable
            size="small"
            onClick={() => nav.open(`autumnbox://${app.id}`)}
          >
            <Typography.Text ellipsis>{app.name}</Typography.Text>
          </Card>
        </Col>
      ))}
    </Row>
  );
};

# 动态注册与注销

大多数情况下,App 通过 defineApp() + __entry__.ts 自动注册。但如果需要在运行时根据条件动态添加或移除 App:

import type { PluginContext, AutumnApp } from '@autumnbox/sdk';
import { AppService } from '@autumnbox/sdk/hooks';
import { MyDynamicApp } from './apps/MyDynamicApp';

export function pluginMain(context: PluginContext): () => void {
  const appService = context.getService(AppService);

  const app: AutumnApp = {
    id: 'my-dynamic-app',
    name: 'app.name.dynamic',
    component: MyDynamicApp,
    shallSelectAdbDevice: true,
    tags: ['tools'],
  };

  appService.register({
    app,
    pluginPackageName: context.pluginPackageName,
  });

  return () => {
    appService.unregister('my-dynamic-app');
  };
}

当插件被卸载时,宿主会自动调用 unregisterByPluginPackageName 清理该插件注册的所有 App,无需手动处理。

# 下一步