AppRegistry注册机制
学完本章后,你能说出:
-
registerComponent 和 runApplication 的关系 -
为什么 appKey 必须匹配 -
Expo 项目的注册点在哪里
AppRegistry 的两个核心方法
// AppRegistry.js(React Native JS 层)// ========== 方法 1:注册根组件(JS 调用)==========export function registerComponent(appKey: string,getRootComponent: () => React.ComponentType) {// 存到 Native 可访问的注册表modules[appKey] = getRootComponentregisterCallableModule(appKey, getRootComponent)}// ========== 方法 2:运行应用(Native 调用)==========export function runApplication(appKey: string, appParameters: any) {const RootComponent = modules[appKey]if (!RootComponent) {// 错误:appKey 不匹配!throw new Error(`App with appKey "${appKey}" is not registered. ` +`Did you forget to call AppRegistry.registerComponent?`)}// 触发 React renderrenderApplication(RootComponent, appParameters)}
Expo 项目的注册点
// node_modules/expo-router/entry.js// Expo 项目的真正入口文件import { AppRegistry } from 'react-native'// registerRootComponent 内部执行:AppRegistry.registerComponent('main', () => {// 返回 expo-router 的根组件return require('expo-router/src/view/EntryRoute').default})// 实际等价于:// AppRegistry.registerComponent('main', RootComponent)
为什么 appKey 必须匹配?
【正确情况】Native: moduleName = "main" 或 getMainComponentName() = "main"JS: AppRegistry.registerComponent('main', ...)↓Native 调用 runApplication("main", ...)↓JS 注册表中找到 "main" → 渲染 ✓【错误情况】Native: moduleName = "MyApp"JS: AppRegistry.registerComponent('main', ...)↓Native 调用 runApplication("MyApp", ...)↓JS 注册表中只有 "main" → 找不到!↓崩溃 ❌
验证
# 验证 1:找到 expo-router 的 registerComponent 调用cat node_modules/expo-router/entry.js# 验证 2:确认 Android appKeygrep -n "main" android/app/src/main/java/com/yourapp/MainActivity.kt# 验证 3:确认 iOS appKey(Swift AppDelegate)grep -n "moduleName" ios/YourApp/AppDelegate.swift# 或grep -n '"main"' ios/YourApp/AppDelegate.swift# 验证 4:确认 iOS AppDelegate 是 Swift(不是 .mm)find ios -name "AppDelegate.swift"find ios -name "AppDelegate.mm" # 旧版项目才有,新版应无输出# 验证 5:模拟 appKey 错误# 修改 iOS AppDelegate.swift 的 moduleName 为 "wrong"# 或修改 Android MainActivity.kt 的 getMainComponentName() 返回 "wrong"# 运行 App,观察崩溃日志# 错误信息应为:"App with appKey "wrong" is not registered"
夜雨聆风