此 wiki 页面记录了 Tauri 的应用程序状态管理系统,该系统允许在您的应用程序中共享和访问全局状态。Tauri 中的状态管理允许您存储和访问在整个应用程序生命周期中需要可用的数据,例如数据库连接、配置设置或任何共享资源。
有关管理窗口状态的信息,请参阅 窗口管理,有关基于事件的通信,请参阅 事件系统。
Tauri 的状态管理围绕几个关键组件构建
StateManager:存储和管理所有应用程序状态的中央注册表State<T>:一种 guard 类型,可提供对状态值的安全、类型化访问Manager trait:提供注册和检索状态的方法状态管理系统是基于类型的,而不是基于键的,这意味着您通过其 Rust 类型而不是字符串标识符来注册和检索状态值。
来源:crates/tauri/src/state.rs19-51 crates/tauri/src/lib.rs696-755
Tauri 的状态管理系统将值存储在线程安全的容器中,可以在应用程序的任何位置访问。 StateManager 维护一个从类型 ID 到实际值的映射,从而实现类型安全检索。
当您使用 manage() 注册状态时,会发生以下情况
TypeId::of<T>() 计算值的类型 ID当您使用 state() 或 try_state() 请求状态时
State<T> guard,它提供了对底层值的安全访问来源:crates/tauri/src/state.rs111-173 crates/tauri/src/lib.rs696-755
状态通常在应用程序设置期间注册
manage() 方法返回一个布尔值,指示状态是新注册的(true)还是已存在的(false)。
状态可以通过几种方式访问
使用 state() 方法:
使用 try_state() 方法(如果找不到状态则不会 panic)
在命令处理程序中使用 State 参数:
来源:crates/tauri/src/lib.rs626-747 crates/tauri/src/state.rs19-51
重要的是,由于状态值在整个应用程序中共享并且必须是 Send + Sync + 'static,因此可变性只能通过内部可变性模式进行
来源:crates/tauri/src/lib.rs626-655 crates/tauri/src/state.rs19-51
StateManager 是状态管理系统的核心。它维护一个从类型 ID 到值的映射
该映射由互斥锁保护以确保线程安全,并且值被固定以确保其内存位置保持稳定。
State<T> 类型是对值引用的简单包装
它实现了 Deref 到底层类型,使其易于使用。
StateManager 提供了一个 unmanage<T>() 方法,允许删除状态,但此方法不安全,并且自 2.3.0 版本以来已被弃用。删除状态可能会导致先前获得的 State 对象出现悬空引用。
更安全的选择是使用内部可变性模式,例如 Mutex<Option<T>>,其中可以在不删除状态本身的情况下获取内部值。
来源:crates/tauri/src/state.rs101-150 crates/tauri/src/lib.rs719-729
State<T> 类型实现了 CommandArg,允许将其用作命令处理程序中的参数
此实现允许在从 JavaScript 调用命令时自动提取状态。
来源:crates/tauri/src/state.rs60-70
应用程序管理器维护一个 Arc<StateManager>,用于在整个应用程序中访问状态
这使得任何拥有 AppManager 访问权限的组件都可以访问应用程序状态。
来源:crates/tauri/src/manager/mod.rs190-227
这是一个定义、注册和使用状态的完整示例
来源:crates/tauri/src/lib.rs626-655 crates/tauri/src/state.rs19-51
Tauri 使用一个专门的哈希映射来存储状态,该映射针对 TypeId 键进行了优化
IdentHash 是一个针对 TypeId 值(它们本身就是唯一的整数)进行性能优化的哈希器,它只是直接使用输入值作为哈希。
状态值使用 Pin<Box<dyn Any + Sync + Send>> 固定在内存中。这确保了存储值内存位置不变,这对于 state() 和 try_state() 返回的引用的安全性很重要。
来源:crates/tauri/src/state.rs72-98 crates/tauri/src/state.rs101-110
状态管理系统设计得非常高效,开销最小
IdentHash 为 TypeId 提供零开销哈希State<T> 提供引用,无需复制数据设计应用程序时,请考虑
来源:crates/tauri/src/state.rs72-98 crates/tauri/src/lib.rs696-755
Mutex、RwLock 等)unmanage:切勿使用已弃用的 unmanage 方法,因为它可能导致悬空引用try_state:当不确定状态是否存在时,请使用 try_state 而不是 state 来避免 panic来源: crates/tauri/src/lib.rs719-729 crates/tauri/src/lib.rs626-655