Activity Manager

Activity Manager is a UI-agnostic, Android-style activity and routing stack manager for Rust.
它是一个无 UI 框架依赖的通用 Android 风格页面(Activity)与路由堆栈管理框架。
本框架通过 ActivityHost 抽象了底层的 UI 渲染和事件循环机制,使得核心的路由调度和生命周期管理逻辑可以独立于特定的 UI 框架(如 Iced)运行。
🌟 核心特性 (Core Features)
- 高度解耦 (UI-Agnostic): 完全剥离具体 UI 框架依赖,通过
ActivityHost Trait 适配任意 UI 库。
- 生命周期管理 (Lifecycle): 提供
on_create, on_resume, on_pause, on_destroy, on_new_intent 等完整的生命周期流转。
- 经典启动模式 (Launch Modes): 完美还原 Android 的四种经典启动模式:
Standard: 标准新建模式
SingleTop: 栈顶复用模式
SingleTask: 栈内复用模式 (Clear Top)
SingleInstance: 全局单例独占模式
- 半透明叠加渲染 (Painter's Algorithm): 原生支持 Dialog 风格的半透明页面叠加,智能阻断底层被遮挡页面的无效渲染与无效事件订阅。
- 依赖注入 (DI): 在 Activity 创建时通过工厂闭包自动注入全局 Context。
📦 安装 (Installation)
在你的 Cargo.toml 中添加:
[dependencies]
activity-manager = "0.1.0"
或者使用命令快速添加:
cargo add activity-manager
📖 完整使用指南 (Usage Guide)
Activity Manager 的核心思想是**“托管”**。你需要将它嵌入到你所使用的具体 UI 框架(如 Iced 等)的主状态机中。以下演示如何在一个典型的应用生命周期中集成并使用本框架。
1. 定义你的环境:Host 与 Route
首先,告诉框架你所使用的 UI 底层类型(Host)以及你的页面路由表(Route)。
use activity_manager::{ActivityHost, LaunchMode, Route};
pub struct AppHost;
impl ActivityHost for AppHost {
type View = String; type Effect = (); type Subscription = (); type Message = AppMessage; }
#[derive(Debug, Clone)]
pub enum AppMessage {
GoToSettings,
GoBack,
UserClickedButton,
}
#[derive(Debug, Clone, PartialEq)]
pub enum AppRoute {
Home,
Settings,
}
impl Route for AppRoute {
fn launch_mode(&self) -> LaunchMode {
match self {
AppRoute::Home => LaunchMode::SingleTask,
AppRoute::Settings => LaunchMode::Standard,
}
}
fn is_translucent(&self) -> bool { false }
}
2. 编写你的 Activity (页面)
每个页面都是一个独立的状态机,只需实现 Activity 接口:
use activity_manager::{Activity, Intent};
#[derive(Clone)]
pub struct AppContext {
pub user_token: String,
}
pub struct HomeActivity;
impl Activity<AppRoute, AppHost, AppContext> for HomeActivity {
fn route(&self) -> AppRoute { AppRoute::Home }
fn update(&mut self, message: AppMessage) -> Vec<()> {
match message {
AppMessage::UserClickedButton => {
println!("Button clicked on Home!");
vec![] }
_ => vec![]
}
}
fn view(&self) -> String {
"<h1>Welcome Home</h1>".to_string()
}
}
3. 在应用主循环中集成 Manager
这是最关键的一步。你需要将 ActivityManager 存放在你应用的最顶层状态中,并将应用的 update 和 view 委托给 Manager。
use activity_manager::{ActivityManager, Intent};
pub struct MyApplication {
manager: ActivityManager<AppRoute, AppHost, AppContext>,
}
impl MyApplication {
pub fn new() -> Self {
let context = AppContext { user_token: "123".to_string() };
let factory = Box::new(|route: &AppRoute, _ctx: &AppContext| -> Box<dyn Activity<AppRoute, AppHost, AppContext>> {
match route {
AppRoute::Home => Box::new(HomeActivity),
AppRoute::Settings => unimplemented!(),
}
});
let (manager, _initial_effects) = ActivityManager::new(AppRoute::Home, context, factory);
Self { manager }
}
pub fn update(&mut self, message: AppMessage) -> Vec<()> {
let mut effects = Vec::new();
match message {
AppMessage::GoToSettings => {
let intent = Intent::new(AppRoute::Settings);
effects.extend(self.manager.start_activity(intent));
return effects; }
AppMessage::GoBack => {
effects.extend(self.manager.back());
return effects;
}
_ => {}
}
effects.extend(self.manager.update(message));
effects
}
pub fn view(&self) -> String {
let active_views: Vec<String> = self.manager.views();
format!("<Stack>\n{}\n</Stack>", active_views.join("\n"))
}
}
💡 核心工作流总结
- 渲染流:UI 框架请求视图 ->
MyApplication::view -> manager.views() -> 获取活动页面的 Activity::view 组合并返回。
- 事件流:用户交互 -> UI 框架触发
AppMessage -> MyApplication::update -> 拦截路由消息或透传给 manager.update() -> 栈顶的 Activity::update 接收消息并更新自身状态。
📄 协议 (License)
MIT