npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xiaoxianthis/react-native-applink

v1.1.0

Published

Cross-app shared state & method invocation via AIDL/Binder for React Native Android

Readme

react-native-applink

跨 App 共享状态与方法调用的 React Native 库(仅 Android)。

基于 AIDL / Binder 实现高性能进程间通信,通过 ContentProvider 实现零启动服务发现,封装成 React Hooks,让多个 App 之间共享状态和调用方法像在同一个项目里使用 useState 一样简单。

核心特性

  • useSharedState — 跨 App 的 useState,任何 App 可读写同一状态
  • useSharedMethod — 注册一个可被其他 App 远程调用的方法
  • useRemoteMethod — 调用另一个 App 注册的方法,获取返回值
  • useDiscovery — 发现已安装的生态 App 及其能力列表
  • 签名证书校验 — 仅相同签名的 App 可通信,天然安全
  • 自动拉起 — 目标 App 未启动时自动启动并完成调用
  • 零原生代码 — 使用方无需编写任何 Java/Kotlin 代码

安装

npm install @xiaoxianthis/react-native-applink
# 或
yarn add @xiaoxianthis/react-native-applink

React Native 0.60+ 自动链接,无需手动 link。

前置条件

所有参与通信的 App 必须使用同一个签名证书(keystore)打包。 这是安全机制的基础——库会在运行时校验调用方的签名证书是否与自身一致。 开发阶段所有 App 默认使用 debug.keystore,无需额外配置。

  • Android 7.0+(API 24+)
  • React Native 0.60+

快速开始

1. 包裹 Provider

在每个 App 的根组件中:

import { AppLinkProvider } from '@xiaoxianthis/react-native-applink';

function App() {
  return (
    <AppLinkProvider appId="main">
      <YourApp />
    </AppLinkProvider>
  );
}

appId 仅用于标识,不影响通信路由。

2. 共享状态

import { useSharedState } from '@xiaoxianthis/react-native-applink';

// ---- App A(状态提供者,传入默认值即注册为所有者)----
function UserScreen() {
  const [token, setToken, ready] = useSharedState('auth.token', '');

  return ready ? <Text>{token}</Text> : <Loading />;
}

// ---- App B(状态消费者,不传默认值即自动订阅远端)----
function RemoteUserInfo() {
  const [token, setToken, ready] = useSharedState('auth.token');
  //     ↑ 值来自 App A        ↑ 可远程修改 App A 的值

  return ready ? <Text>Token: {token}</Text> : <Loading />;
}
  • 传入 defaultValue → 注册为该状态的 所有者
  • 不传 defaultValue → 自动发现并 订阅 远端所有者
  • setToken 可跨 App 修改值,所有订阅方实时收到更新
  • ready 表示初始值是否已加载

3. 共享方法

import { useSharedMethod, useRemoteMethod } from '@xiaoxianthis/react-native-applink';

// ---- App A(方法提供者)----
function ScannerScreen() {
  useSharedMethod('scanner.scan', async (params) => {
    const result = await startQRScan(params.type);
    return { data: result };
  }, {
    description: '扫描二维码或条形码',
    parameters: {
      type: 'object',
      properties: {
        type: { type: 'string', description: '码类型: qr | barcode' },
      },
      required: ['type'],
    },
  });

  return <CameraView />;
}

// ---- App B(方法调用者)----
function OrderScreen() {
  const scan = useRemoteMethod('scanner.scan');

  const handleScan = async () => {
    const result = await scan({ type: 'qr' });
    console.log('扫码结果:', result.data);
  };

  return <Button onPress={handleScan} title="扫码" />;
}
  • 如果 App A 没有启动,调用时会自动拉起
  • 方法支持异步,返回值自动序列化传输
  • 超时默认 15 秒
  • schema 参数可选,不传则和以前一样只注册方法名

4. 发现已安装的 App

import { useDiscovery } from '@xiaoxianthis/react-native-applink';

function EcosystemScreen() {
  const { apps, initialized, refresh } = useDiscovery();

  return (
    <FlatList
      data={apps}
      renderItem={({ item }) => (
        <View>
          <Text>{item.appName}</Text>
          <Text>状态: {item.states.join(', ')}</Text>
          <Text>方法: {item.methods.map(m => m.name).join(', ')}</Text>
        </View>
      )}
    />
  );
}

methods 数组中每个元素为 { name, schema? } 对象。schema 仅在注册时提供了才会出现。

架构总览

┌──────────────────────────────────────────────────────────────┐
│  JS Layer (React Hooks)                                      │
│                                                              │
│  useSharedState ──→ AppLinkProvider ──→ NativeAppLink         │
│  useSharedMethod     (Context + Event Bus)                   │
│  useRemoteMethod                                             │
│  useDiscovery                                                │
├──────────────────────────────────────────────────────────────┤
│  Native Bridge (AppLinkModule)                               │
│                                                              │
│  ┌─────────────┐  ┌───────────────┐  ┌──────────────────┐   │
│  │ StateStore   │  │ MethodHandler │  │ ConnectionManager│   │
│  │ (SharedPref) │  │ (Future+Event)│  │ (Binder Pool)   │   │
│  └─────────────┘  └───────────────┘  └──────────────────┘   │
├──────────────────────────────────────────────────────────────┤
│  IPC Layer                                                   │
│                                                              │
│  ContentProvider ─── 服务发现(App 未启动也可查询)            │
│  AIDL Service    ─── 状态读写 / 方法调用 / 订阅推送           │
│  SecurityVerifier ── 签名证书校验                             │
└──────────────────────────────────────────────────────────────┘

API 参考

<AppLinkProvider appId="string">

| Prop | 类型 | 说明 | |------|------|------| | appId | string | 当前 App 标识(仅用于日志/调试) |

useSharedState(key, defaultValue?)

| 参数 | 类型 | 说明 | |------|------|------| | key | string | 全局唯一的状态键名 | | defaultValue | any | 可选,提供则注册为所有者 |

返回 [value, setter, isReady]

useSharedMethod(name, handler, schema?)

| 参数 | 类型 | 说明 | |------|------|------| | name | string | 全局唯一的方法名 | | handler | (params) => Promise<any> | 处理函数 | | schema | MethodSchema | 可选,JSON Schema 描述(兼容 Vercel AI SDK tool 格式) |

MethodSchema 结构:

{
  description?: string;          // 方法功能描述
  parameters?: object;           // JSON Schema,描述输入参数
  returns?: object;              // JSON Schema,描述返回值(仅供参考)
}

useRemoteMethod(name)

返回 async (params?) => Promise<any>

useDiscovery()

返回 { apps, initialized, refresh }

安全模型

  1. 签名证书校验:每次 AIDL 调用前,服务端取 Binder.getCallingUid() 对应的包签名哈希,与自身比对。不一致则拒绝。
  2. 自动生效:所有使用同一 keystore 签名的 App 自动互信,无需配置。
  3. 无自定义权限冲突:不使用 <permission> 声明,避免多 App 安装时的权限冲突问题。

AI Agent 集成

方法的 schema 采用标准 JSON Schema 格式,可直接对接 Vercel AI SDK 等 LLM 工具调用框架:

import { tool, jsonSchema } from 'ai';
import { useDiscovery } from '@xiaoxianthis/react-native-applink';

const { apps } = useDiscovery();

// 将所有子 App 的方法自动转为 AI SDK tools
const tools = {};
for (const app of apps) {
  for (const method of app.methods) {
    if (!method.schema) continue;
    tools[method.name] = tool({
      description: method.schema.description,
      inputSchema: jsonSchema(method.schema.parameters),
      execute: async (params) =>
        invokeRemoteMethod(app.packageName, method.name, params),
    });
  }
}

注意事项

  • 状态键名全局唯一:建议使用 appId.stateName 格式命名(如 main.userTokenstore.cartItems
  • 首次运行:App 至少运行一次后,其注册的状态和方法才会被 ContentProvider 缓存并可被发现
  • 方法调用 App 拉起:如果目标 App 未在前台运行,调用方法时会自动拉起其主 Activity
  • 序列化:所有跨进程数据均为 JSON 序列化,确保状态值可被 JSON.stringify / JSON.parse 处理

项目结构

react-native-applink/
├── index.js                          # 入口
├── src/
│   ├── AppLinkProvider.js            # React Context Provider + 事件总线
│   ├── AppLinkContext.js             # Context 定义
│   ├── NativeAppLink.js              # Native Module 封装
│   └── hooks/
│       ├── useSharedState.js         # 跨 App useState
│       ├── useSharedMethod.js        # 注册可被远程调用的方法
│       ├── useRemoteMethod.js        # 调用远端方法
│       └── useDiscovery.js           # 发现生态 App
├── android/
│   ├── build.gradle
│   └── src/main/
│       ├── AndroidManifest.xml       # 自动合并:Provider + Service
│       ├── aidl/com/applink/
│       │   ├── IAppLinkService.aidl  # 跨进程接口
│       │   └── IAppLinkCallback.aidl # 状态订阅回调
│       └── java/com/applink/
│           ├── AppLinkPackage.java   # RN 注册入口
│           ├── AppLinkModule.java    # RN Native Module
│           ├── AppLinkService.java   # AIDL Bound Service
│           ├── AppLinkContentProvider.java  # 服务发现
│           ├── AppLinkCore.java      # 单例核心
│           ├── SecurityVerifier.java # 签名校验
│           ├── StateStore.java       # 状态持久化
│           ├── MethodHandler.java    # 方法调用桥接
│           └── ConnectionManager.java # Binder 连接池
├── package.json
└── react-native.config.js

License

MIT