This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
教程:创建一个原生模块
编辑页面
使用 Expo Modules API 创建一个可持久化设置的原生模块教程。
在本教程中,你将构建一个模块,用于存储用户偏好的应用主题:深色、浅色或系统默认。在 Android 上,使用 SharedPreferences;在 iOS 上,使用 UserDefaults。你还可以使用 localStorage 实现 Web 支持,但本教程不涉及这部分。

构建一个使用 SharedPreferences(Android)和 UserDefaults(iOS)持久化用户设置的原生模块。
1
2
3
4
获取、设置并持久化主题偏好值
Android 原生模块
要读取该值,请查找键 "theme" 下的 SharedPreferences 字符串。如果该键不存在,则默认值为 "system"。使用 reactContext(React Native 的 ContextWrapper)通过 getSharedPreferences() 访问 SharedPreferences 实例。
要设置该值,请使用 SharedPreferences 的 edit() 方法获取一个 Editor 实例。然后使用 putString() 设置值。确保 setTheme 函数接受 String 类型的值。
iOS 原生模块
要在 iOS 上读取该值,请查找键 "theme" 下的 UserDefaults 字符串。如果该键不存在,则默认值为 "system"。
要设置该值,请使用 UserDefaults 的 set(_:forKey:) 方法。确保 setTheme 函数接受 String 类型的值。
TypeScript 模块
更新 ExpoSettingsModule.ts,为 ExpoSettingsModule 原生模块添加一个 TypeScript 接口,以便更新主题。
现在,从 TypeScript 中调用你的原生模块。
示例应用
现在你可以在示例应用中使用 Settings API。
当你重新构建并运行应用时,仍然会设置为“system”主题。点击按钮不会产生任何效果,但当你重新加载应用时,主题会发生变化。这是因为应用没有获取新的主题值或重新渲染。你将在下一步中修复这个问题。
5
为主题值发送变更事件
确保使用你的 API 的开发者可以在主题值变化时做出响应:每当值更新时发送一个变更事件。使用 Events 定义组件来描述模块发出的事件,使用 sendEvent 从原生代码发送事件,并使用 EventEmitter API 在 JavaScript 中订阅事件。事件负载为 { theme: string }。
Android 原生模块
事件负载在 Android 上表示为 Bundle 实例,你可以使用 bundleOf 函数创建它。
iOS 原生模块
TypeScript 模块
示例应用
6
使用枚举提高类型安全
在当前形式下使用 Settings.setTheme() API 很容易出错,因为它允许任何字符串值。通过使用枚举将可能的值限制为 system、light 和 dark,来提升这个 API 的类型安全性。
Android 原生模块
iOS 原生模块
TypeScript 模块
示例应用
如果你将 Settings.setTheme(nextTheme) 改为 Settings.setTheme("not-a-real-theme"),TypeScript 会报错。如果你忽略该错误并点击按钮,你会看到如下运行时错误:
ERROR Error: FunctionCallException: Calling the 'setTheme' function has failed (at ExpoModulesCore/SyncFunctionComponent.swift:76) → Caused by: ArgumentCastException: Argument at index '0' couldn't be cast to type Enum<Theme> (at ExpoModulesCore/JavaScriptUtils.swift:41) → Caused by: EnumNoSuchValueException: 'not-a-real-theme' is not present in Theme enum, it must be one of: 'light', 'dark', 'system' (at ExpoModulesCore/Enumerable.swift:37)
错误信息的最后一行表明,not-a-real-theme 不是 Theme 枚举的有效值。唯一有效的值是 light、dark 和 system。
恭喜!你已经为 Android 和 iOS 创建了你的第一个 Expo 模块。
下一步
使用 Kotlin 和 Swift 创建原生模块。
关于使用 Expo Modules API 创建原生视图的教程。