当前位置: 首页 > news >正文

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 核心价值

  • 解耦性:各模块独立管理路由,不依赖中央配置
  • 轻量化:避免复杂的路由图,使用简单的字符串映射
  • 灵活性:支持动态注册和反射调用
  • 易维护:新增模块只需添加路由注册,修改模块不影响其他模块

这种自定义路由方案完全符合你的需求:纯组件化、各模块独立、轻量级解决方案。通过反射机制和简单的字符串映射,实现了高效的路由系统。

http://www.dtcms.com/a/279425.html

相关文章:

  • ServiceLibrary 库使用演示
  • [AI8051U入门第一步]环境安装和按键控制流水灯
  • 将dist文件打包成exe可执行程序
  • MySQL服务故障分析报告​​
  • 以楼宇自控系统为抓手,实现人居环境优化与建筑能效跃升
  • 职业教育领域的“101计划
  • keepalive模拟操作部署
  • 学习日志09 python
  • 【SVN】SVN 客户端的安装与操作
  • 设计模式之代理模式:掌控对象访问的优雅之道
  • CVE-2017-7525源码分析与漏洞复现(Jackson 反序列化)
  • Android 中 实现格式化字符串
  • vue2/3生命周期使用建议
  • TCL在芯片设计与验证中的应用实践
  • WinUI3开发_Combobox实现未展开时是图标下拉菜单带图标+文字
  • ConcurrentHashMap 原子操作详解:computeIfAbsent、computeIfPresent和putIfAbsent
  • 技术人生——第12集:思想为王,功能在后
  • (5)LangGraph4j框架ReActAgent实现
  • mit6.5840-lab4C-Snapshot-25Summer
  • Java Stream流详解
  • 文心一言 4.5 开源深度剖析:中文霸主登场,开源引擎重塑大模型生态
  • C++11 std::is_permutation:从用法到原理的深度解析
  • 什么是延迟双删
  • 算法训练营day18 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
  • 通过 ip a 查看网络接口名
  • 【算法】贪心算法:摆动序列C++
  • 2025js——面试题(8)-http
  • Linux 系统下的 Sangfor VDI 客户端安装与登录完全攻略 (CentOS、Ubuntu、麒麟全线通用)
  • 程序跑飞是什么?
  • 核电概念盘中异动,中核科技涨停引领板块热度