Android 自定义路由系统
1. 设计理念
适用场景
- 纯组件化,各 module 独立
- 跳转逻辑简单,不需要复杂导航图
- 希望轻量级解决方案
工作原理
- 定义路由接口
- 各 module 注册自己的路由
- 通过路由名查找类名,用反射或 setClassName 跳转
2. 项目结构
MyApp/
├── app/ # 主应用模块
│ ├── src/main/java/com/robot/app/
│ │ ├── MainApplication.kt
│ │ └── MainActivity.kt
│ └── build.gradle
├── lib_common/ # 公共库模块
│ ├── src/main/java/com/robot/common/router/
│ │ ├── IRouter.kt
│ │ ├── Router.kt
│ │ ├── RouteInterceptor.kt
│ │ ├── RouteCallback.kt
│ │ └── RouteConstants.kt
│ └── build.gradle
├── mod_home/ # 首页模块
│ ├── src/main/java/com/robot/mod_home/
│ │ ├── HomeActivity.kt
│ │ ├── SettingsActivity.kt
│ │ ├── ProfileActivity.kt
│ │ └── router/HomeRouter.kt
│ └── build.gradle
├── mod_user/ # 用户模块
│ ├── src/main/java/com/robot/mod_user/
│ │ ├── LoginActivity.kt
│ │ ├── RegisterActivity.kt
│ │ ├── UserProfileActivity.kt
│ │ └── router/UserRouter.kt
│ └── build.gradle
├── mod_product/ # 商品模块
│ ├── src/main/java/com/robot/mod_product/
│ │ ├── ProductListActivity.kt
│ │ ├── ProductDetailActivity.kt
│ │ ├── ShoppingCartActivity.kt
│ │ └── router/ProductRouter.kt
│ └── build.gradle
└── settings.gradle
3. 核心代码实现
3.1 路由接口 (lib_common)
// IRouter.ktinterface IRouter {fun registerRoute(routeName: String, className: String)fun getClassName(routeName: String): String?fun navigate(context: Context, routeName: String, params: Map<String, Any>? = null)fun registerInterceptor(interceptor: RouteInterceptor)}// RouteInterceptor.ktinterface RouteInterceptor {fun intercept(context: Context, routeName: String, params: Map<String, Any>?): Boolean}// RouteCallback.ktinterface RouteCallback {fun onRouteSuccess(routeName: String)fun onRouteFailed(routeName: String, error: String)}// RouteConstants.ktobject RouteConstants {object Home {const val MAIN = "/home/main"const val SETTINGS = "/home/settings"const val PROFILE = "/home/profile"}object User {const val LOGIN = "/user/login"const val REGISTER = "/user/register"const val PROFILE = "/user/profile"}object Product {const val LIST = "/product/list"const val DETAIL = "/product/detail"const val CART = "/product/cart"}}
3.2 路由实现 (lib_common)
// Router.ktobject Router : IRouter {private val routeMap = mutableMapOf<String, String>()private val interceptors = mutableListOf<RouteInterceptor>()private var routeCallback: RouteCallback? = nulloverride fun registerRoute(routeName: String, className: String) {routeMap[routeName] = classNameLog.d("Router", "Registered route: $routeName -> $className")}override fun getClassName(routeName: String): String? {return routeMap[routeName]}override fun navigate(context: Context, routeName: String, params: Map<String, Any>? = null) {try {// 执行拦截器for (interceptor in interceptors) {if (interceptor.intercept(context, routeName, params)) {Log.d("Router", "Route intercepted: $routeName")return}}val className = getClassName(routeName)if (className != null) {val clazz = Class.forName(className)val intent = Intent(context, clazz)// 传递参数params?.forEach { (key, value) ->when (value) {is String -> intent.putExtra(key, value)is Int -> intent.putExtra(key, value)is Boolean -> intent.putExtra(key, value)is Float -> intent.putExtra(key, value)is Long -> intent.putExtra(key, value)is Double -> intent.putExtra(key, value)is Parcelable -> intent.putExtra(key, value)is Serializable -> intent.putExtra(key, value)}}context.startActivity(intent)routeCallback?.onRouteSuccess(routeName)Log.d("Router", "Navigation successful: $routeName")} else {val error = "Route not found: $routeName"Log.e("Router", error)routeCallback?.onRouteFailed(routeName, error)}} catch (e: Exception) {val error = "Navigation failed: ${e.message}"Log.e("Router", error, e)routeCallback?.onRouteFailed(routeName, error)}}override fun registerInterceptor(interceptor: RouteInterceptor) {interceptors.add(interceptor)}fun setRouteCallback(callback: RouteCallback) {this.routeCallback = callback}}
4. 模块路由注册
4.1 首页模块 (mod_home)
// HomeRouter.ktobject HomeRouter {fun initRoutes() {Router.registerRoute(RouteConstants.Home.MAIN, "com.robot.mod_home.HomeActivity")Router.registerRoute(RouteConstants.Home.SETTINGS, "com.robot.mod_home.SettingsActivity")Router.registerRoute(RouteConstants.Home.PROFILE, "com.robot.mod_home.ProfileActivity")}}// HomeActivity.ktclass HomeActivity : AppCompatActivity() {companion object {init {Router.registerRoute(RouteConstants.Home.MAIN, "com.robot.mod_home.HomeActivity")}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_home)// 处理路由参数val fromLogin = intent.getBooleanExtra("from_login", false)if (fromLogin) {showWelcomeMessage()}}}// SettingsActivity.ktclass SettingsActivity : AppCompatActivity() {companion object {init {Router.registerRoute(RouteConstants.Home.SETTINGS, "com.robot.mod_home.SettingsActivity")}}}// ProfileActivity.ktclass ProfileActivity : AppCompatActivity() {companion object {init {Router.registerRoute(RouteConstants.Home.PROFILE, "com.robot.mod_home.ProfileActivity")}}}
4.2 用户模块 (mod_user)
// UserRouter.ktobject UserRouter {fun initRoutes() {Router.registerRoute(RouteConstants.User.LOGIN, "com.robot.mod_user.LoginActivity")Router.registerRoute(RouteConstants.User.REGISTER, "com.robot.mod_user.RegisterActivity")Router.registerRoute(RouteConstants.User.PROFILE, "com.robot.mod_user.UserProfileActivity")}}// LoginActivity.ktclass LoginActivity : BaseMvvmActivity<ActivityLoginBinding, LoginViewModel>() {override fun initData() {mViewModel.loginLiveData.observe(this) { token ->if (token != null) {// 登录成功后跳转到首页val params = mapOf("from_login" to true)Router.navigate(this, RouteConstants.Home.MAIN, params)finish()}}}companion object {init {Router.registerRoute(RouteConstants.User.LOGIN, "com.robot.mod_user.LoginActivity")}}}// RegisterActivity.ktclass RegisterActivity : AppCompatActivity() {companion object {init {Router.registerRoute(RouteConstants.User.REGISTER, "com.robot.mod_user.RegisterActivity")}}}// UserProfileActivity.ktclass UserProfileActivity : AppCompatActivity() {companion object {init {Router.registerRoute(RouteConstants.User.PROFILE, "com.robot.mod_user.UserProfileActivity")}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_user_profile)// 接收用户ID参数val userId = intent.getStringExtra("user_id")loadUserProfile(userId)}}
4.3 商品模块 (mod_product)
// ProductRouter.ktobject ProductRouter {fun initRoutes() {Router.registerRoute(RouteConstants.Product.LIST, "com.robot.mod_product.ProductListActivity")Router.registerRoute(RouteConstants.Product.DETAIL, "com.robot.mod_product.ProductDetailActivity")Router.registerRoute(RouteConstants.Product.CART, "com.robot.mod_product.ShoppingCartActivity")}}// ProductListActivity.ktclass ProductListActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_product_list)setupRecyclerView()}private fun onProductClick(productId: String, productName: String) {val params = mapOf("product_id" to productId,"product_name" to productName)Router.navigate(this, RouteConstants.Product.DETAIL, params)}companion object {init {Router.registerRoute(RouteConstants.Product.LIST, "com.robot.mod_product.ProductListActivity")}}}// ProductDetailActivity.ktclass ProductDetailActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_product_detail)// 接收商品参数val productId = intent.getStringExtra("product_id")val productName = intent.getStringExtra("product_name")loadProductDetail(productId, productName)}companion object {init {Router.registerRoute(RouteConstants.Product.DETAIL, "com.robot.mod_product.ProductDetailActivity")}}}// ShoppingCartActivity.ktclass ShoppingCartActivity : AppCompatActivity() {companion object {init {Router.registerRoute(RouteConstants.Product.CART, "com.robot.mod_product.ShoppingCartActivity")}}}
5. 应用初始化
5.1 主应用 (app)
// MainApplication.ktclass MainApplication : Application() {override fun onCreate() {super.onCreate()// 初始化各模块路由HomeRouter.initRoutes()UserRouter.initRoutes()ProductRouter.initRoutes()// 注册拦截器Router.registerInterceptor(AuthInterceptor())Router.registerInterceptor(LoggingInterceptor())// 设置路由回调Router.setRouteCallback(object : RouteCallback {override fun onRouteSuccess(routeName: String) {Log.d("Router", "Route success: $routeName")}override fun onRouteFailed(routeName: String, error: String) {Log.e("Router", "Route failed: $routeName - $error")}})}}// MainActivity.ktclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 根据启动参数决定跳转到哪个页面handleLaunchIntent()}private fun handleLaunchIntent() {val targetRoute = intent.getStringExtra("target_route")if (!targetRoute.isNullOrEmpty()) {Router.navigate(this, targetRoute)finish()} else {// 默认跳转到首页Router.navigate(this, RouteConstants.Home.MAIN)finish()}}}
6. 拦截器实现
// AuthInterceptor.ktclass AuthInterceptor : RouteInterceptor {override fun intercept(context: Context, routeName: String, params: Map<String, Any>?): Boolean {// 需要登录的路由val authRequiredRoutes = listOf(RouteConstants.User.PROFILE, RouteConstants.Product.CART)if (authRequiredRoutes.contains(routeName)) {if (!isUserLoggedIn()) {// 跳转到登录页面Router.navigate(context, RouteConstants.User.LOGIN)return true // 拦截原路由}}return false}private fun isUserLoggedIn(): Boolean {return SharedPrefs.getBoolean("is_logged_in", false)}}// LoggingInterceptor.ktclass LoggingInterceptor : RouteInterceptor {override fun intercept(context: Context, routeName: String, params: Map<String, Any>?): Boolean {Log.d("Router", "Navigating to: $routeName with params: $params")return false // 不拦截,只记录日志}}
7. 使用示例
7.1 简单跳转
// 跳转到首页
Router.navigate(this, RouteConstants.Home.MAIN)
// 跳转到登录页
Router.navigate(this, RouteConstants.User.LOGIN)
7.2 带参数跳转
// 跳转到商品详情val params = mapOf("product_id" to "12345","product_name" to "iPhone 15")Router.navigate(this, RouteConstants.Product.DETAIL, params)// 跳转到用户资料val params = mapOf("user_id" to "user123")Router.navigate(this, RouteConstants.User.PROFILE, params)
8. 构建配置
8.1 settings.gradle
include ':app'include ':lib_common'include ':mod_home'include ':mod_user'include ':mod_product'
8.2 app/build.gradle
dependencies {implementation project(':lib_common')implementation project(':mod_home')implementation project(':mod_user')implementation project(':mod_product')}
8.3 各模块 build.gradle
// lib_common/build.gradledependencies {implementation 'androidx.appcompat:appcompat:1.6.1'}// mod_home/build.gradledependencies {implementation project(':lib_common')implementation 'androidx.appcompat:appcompat:1.6.1'}// mod_user/build.gradledependencies {implementation project(':lib_common')implementation 'androidx.appcompat:appcompat:1.6.1'}// mod_product/build.gradledependencies {implementation project(':lib_common')implementation 'androidx.appcompat:appcompat:1.6.1'}
9. 优势总结
9.1 优点
- ✅ 实现简单,学习成本低
- ✅ 内存占用小,性能优秀
- ✅ 模块间解耦,易于维护
- ✅ 支持参数传递和拦截器
- ✅ 各模块独立管理路由
9.2 适用场景
- ✅ 纯组件化架构
- ✅ 模块间跳转逻辑简单
- ✅ 团队规模较小,沟通成本低
- ✅ 对性能要求较高
9.3 核心价值
- 解耦性:各模块独立管理路由,不依赖中央配置
- 轻量化:避免复杂的路由图,使用简单的字符串映射
- 灵活性:支持动态注册和反射调用
- 易维护:新增模块只需添加路由注册,修改模块不影响其他模块
这种自定义路由方案完全符合你的需求:纯组件化、各模块独立、轻量级解决方案。通过反射机制和简单的字符串映射,实现了高效的路由系统。