后附源码地址
MyRouterProject - Android + Flutter 混合路由演示
基于 common_router 路由 SDK 的 Android + Flutter 混合路由演示项目,覆盖四种跨端跳转场景。
应用截图
Native 首页

Flutter 演示页

项目结构
MyRouterProject/
├── common_router/ # 路由核心 SDK(Android Library)
│ └── src/main/java/com/example/mall/common/common_router/
│ ├── MyRouter.kt # 统一路由管理器(核心入口)
│ ├── RouteConfigLoader.kt # 路由配置加载器(解析 JSON)
│ ├── RouteRegistry.kt # 路由注册中心
│ ├── PageStackManager.kt # 页面栈管理器
│ ├── RouterInitializer.kt # 导航器注入器
│ ├── model/ # 数据模型
│ │ ├── RouteType.kt # 路由类型枚举
│ │ ├── RouteConfig.kt # 配置数据模型
│ │ ├── NavigationResult.kt # 导航结果密封类
│ │ ├── PageRecord.kt # 页面记录
│ │ └── LaunchMode.kt # 启动模式枚举
│ └── navigator_interface/
│ ├── INativeNavigator.kt # Native 导航器接口
│ └── IFlutterNavigator.kt # Flutter 导航器接口
│
├── app/ # 宿主 App 模块
│ └── src/main/
│ ├── assets/page_config.json # 路由配置表
│ ├── java/com/example/myrouter/
│ │ ├── MyRouterApplication.kt # Application 入口
│ │ ├── RouterDemoActivity.kt # 路由演示主页(Launcher)
│ │ ├── NativeDemoActivity.kt # Native 演示页
│ │ ├── NativeSecondActivity.kt# Native 第二页
│ │ ├── FlutterRouteActivity.kt# Flutter 桥接 Activity
│ │ └── navigator/
│ │ ├── NativeNavigatorImpl.kt
│ │ └── FlutterNavigatorImpl.kt
│ └── res/layout/
│ ├── activity_router_demo.xml
│ ├── activity_native_demo.xml
│ └── activity_native_second.xml
│
└── feature_flutter/ # Flutter Module
└── lib/
├── main.dart # Flutter 入口(MethodChannel 处理)
├── flutter_router.dart # Flutter 端路由工具类
└── pages/
├── router_demo_flutter_page.dart # Flutter 路由演示页
├── flutter_page_a.dart # Flutter 页面 A
└── flutter_page_b.dart # Flutter 页面 B
架构
App 层 路由 SDK Flutter
┌──────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ MyRouterApp │────>│ MyRouter │ │ FlutterRouter │
│ Application │ │ ├─ push(url) │<───>│ MethodChannel │
│ │ │ ├─ pop() │ │ ├─ navigate() │
│ NativeNavigator │◄───>│ ├─ popTo() │ │ ├─ getParams() │
│ Impl │ │ ├─ buildUrl() │ │ └─ pop() │
│ FlutterNavigator │ │ └─ parseUrl() │ └──────────────────┘
│ Impl │ └──────────────────┘
└──────────────┘
common_router不依赖任何具体 Activity/Flutter 页面,通过接口INativeNavigator/IFlutterNavigator完全解耦- 路由表由
page_config.json驱动,运行时加载,无需硬编码 - Native ↔ Flutter 通过
MethodChannel("com.example.myrouter/router")双向通信
四种跳转场景
| 场景 | 发起端 | 目标端 | 链路 |
|---|---|---|---|
| Native → Flutter | 点击按钮 → MyRouter.push() |
FlutterRouteActivity → Flutter |
FlutterNavigatorImpl → Intent |
| Native → Native | 点击按钮 → MyRouter.push() |
NativeDemoActivity |
NativeNavigatorImpl → Intent |
| Flutter → Native | Flutter 页面按钮 | NativeDemoActivity |
MethodChannel → NativeNavigatorImpl → Intent |
| Flutter → Flutter(跨端) | Flutter 页面按钮 | FlutterRouteActivity |
MethodChannel → FlutterNavigatorImpl → Intent |
| Flutter → Flutter(本地) | Flutter 页面按钮 | Flutter 页面 A/B | Flutter Navigator 内部跳转 |
common_router 集成指南
接入步骤
1. 引入模块
在 settings.gradle.kts 中声明:
kotlin
include(":common_router")
project(":common_router").projectDir = file("common_router")
宿主模块 build.gradle.kts 添加依赖:
kotlin
implementation(project(":common_router"))
2. 实现导航器接口
创建 Native 导航器实现 INativeNavigator:
kotlin
class NativeNavigatorImpl : INativeNavigator {
override fun navigate(
context: Context, path: String, params: Map<String, String>
): NavigationResult {
val intent = when (path) {
"/native/demo" -> Intent(context, NativeDemoActivity::class.java)
else -> return NavigationResult.NotSupported
}
params.forEach { (k, v) -> intent.putExtra(k, v) }
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // Application context 启动必加
context.startActivity(intent)
return NavigationResult.Success
}
override fun canNavigate(path: String) = path.startsWith("/native/")
}
创建 Flutter 导航器实现 IFlutterNavigator:
kotlin
class FlutterNavigatorImpl : IFlutterNavigator {
override fun navigate(
context: Context, path: String, params: Map<String, String>, launchMode: LaunchMode
): NavigationResult {
val intent = Intent(context, FlutterRouteActivity::class.java).apply {
putExtra("page", path)
putExtra("params", params.entries.joinToString(",") { "${it.key}=${it.value}" })
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
return NavigationResult.Success
}
override fun canNavigate(path: String) = path.startsWith("/flutter/")
}
3. 初始化
在 Application.onCreate() 中完成初始化:
kotlin
class MyRouterApplication : Application() {
override fun onCreate() {
super.onCreate()
MyRouter.init(this, "page_config.json")
PageStackManager.clear() // 确保进程复用时栈重置
RouterInitializer.injectNavigators(
nativeNavigator = NativeNavigatorImpl(),
flutterNavigator = FlutterNavigatorImpl()
)
}
}
配置路由表
在 app/src/main/assets/page_config.json 中注册页面:
json
{
"version": "1.0.0",
"routes": [
{"page": "/native/demo", "type": "NATIVE", "description": "Native 演示页"},
{"page": "/flutter/demo", "type": "FLUTTER", "description": "Flutter 演示入口"}
]
}
| 字段 | 说明 | 值 |
|---|---|---|
page |
路由路径(唯一标识) | /native/demo 等 |
type |
页面类型 | NATIVE / FLUTTER |
description |
描述文字 | 任意字符串 |
执行跳转
kotlin
// Native 侧(Android)
MyRouter.push("myrouter://myrouter?page=/native/demo&info={\"from\":\"Home\"}")
// Flutter 侧(Dart)
FlutterRouter.navigate('/native/demo', params: {'from': 'Flutter'})
// 构建 URL
val url = MyRouter.buildUrl("/native/demo", params = mapOf("from" to "Home"))
页面栈管理
kotlin
// 返回上一页
MyRouter.pop()
// 返回到指定页面
MyRouter.popTo("/native/demo")
// 获取当前页面
val current = MyRouter.getCurrentPage()
// Activity 销毁时自动退栈
override fun onDestroy() {
if (isFinishing) MyRouter.pop()
super.onDestroy()
}
Flutter 侧依赖
Flutter 工程依赖 flutter_router.dart,通过 import 'package:feature_flutter/flutter_router.dart' 使用:
dart
// 跳转到 Native 页面
FlutterRouter.navigate('/native/demo');
// 跳转到 Flutter 页面(跨端)
FlutterRouter.navigate('/flutter/pageA');
// 获取 Native 传递的参数
final params = await FlutterRouter.getRouteParams();
// 通知 Native 返回
FlutterRouter.pop();
Flutter 侧通过 MethodChannel("com.example.myrouter/router") 与 Android 通信,Android 端在 FlutterRouteActivity.configureFlutterEngine() 中处理 navigate、getRouteParams、pop 三个方法调用。
构建与运行
前置条件
- JDK 17+
- Android SDK(compileSdk 34, minSdk 24)
- Flutter SDK(^3.9.2)
构建命令
bash
export JAVA_HOME=/path/to/jdk17
# 编译 common_router
./gradlew :common_router:compileDebugKotlin
# 编译 App
./gradlew :app:compileDebugKotlin
# 编译 Flutter Module
cd feature_flutter && flutter pub get && flutter build apk
# 完整构建 APK
./gradlew :app:assembleDebug
路由配置
编辑 app/src/main/assets/page_config.json:
json
{
"version": "1.0.0",
"routes": [
{"page": "/native/demo", "type": "NATIVE", "description": "Native 演示页"},
{"page": "/native/second", "type": "NATIVE", "description": "Native 第二页"},
{"page": "/flutter/demo", "type": "FLUTTER", "description": "Flutter 演示入口"},
{"page": "/flutter/pageA", "type": "FLUTTER", "description": "Flutter 页面 A"},
{"page": "/flutter/pageB", "type": "FLUTTER", "description": "Flutter 页面 B"}
]
}
URL 协议
myrouter://myrouter?page=/native/demo&info={"from":"Home"}&launchMode=STANDARD
page: 路由路径(必填)info: JSON 参数(可选)launchMode: 启动模式(可选,默认 STANDARD)
页面栈管理(还需优化)
PageStackManager 是进程级单例,统一维护跨平台页面栈:
push()--- 入栈(自动防溢出,最大 30 层)pop()--- 出栈replace()--- 替换栈顶clearTo()--- 清空到指定页面clear()--- 清空整个栈
支持五种启动模式:STANDARD、REPLACE、SINGLE_TOP、CLEAR_TOP、NEW_TASK。
未来规划
- 完善页面栈管理,统一管理Native中Activity与Flutter中dart页面,维护统一一套应用栈;完善LaunchMode跳转模式适配。
- 混淆与安全