首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ARouter功能介绍以及实现原理

ARouter功能介绍以及实现原理

原创
作者头像
李林LiLin
发布2025-07-09 16:11:02
发布2025-07-09 16:11:02
15100
代码可运行
举报
文章被收录于专栏:Android进阶编程Android进阶编程
运行总次数:0
代码可运行

一、核心功能

1、页面路由与跳转

  • 跨模块跳转:通过路径(如 /user/profile)代替原生 Intent,实现无依赖的 Activity/Fragment 跳转,支持参数自动注入(如 withString() 传递数据)
  • 降级策略:支持全局/局部降级处理(如页面不存在时跳转统一错误页)
  • 动画与 Flag:支持转场动画(withTransition())和启动模式(withFlags()

2、拦截器(Interceptor)

  • 自定义拦截逻辑:在跳转前执行登录验证、权限检查等操作(如 IInterceptor 接口的 process() 方法)
  • 优先级控制:按优先级顺序执行多个拦截器,支持异步操作
  • 绿色通道:通过 greenChannel() 跳过所有拦截器

3、服务发现与依赖注入

  • 跨模块 API 调用:定义接口(如 UserService),用 @Route 标注实现类,通过 ARouter.getInstance().navigation(UserService.class) 获取实例
  • 依赖注入:使用 @Autowired 自动注入参数(需调用 ARouter.getInstance().inject(this)

4、动态注册与多模块支持

  • 运行时注册路由:通过 addRouteGroup() 动态添加路由,适用于插件化场景
  • 按需加载:路由按分组(Group)初始化,首次访问某分组时才加载

二、实现原理

1、注解处理与路由表生成(编译期)

  • 编译期扫描:APT 扫描项目中的 @Route@Autowired@Interceptor 注解。
  • 代码生成
    • 为每个路由组生成 ARouter$$Group$${groupName} 类。
    • 为每个需要注入的类生成 {ClassName}$$Autowired 注入器。
    • 生成 ARouter$$Interceptors 拦截器注册类。
  • 分组管理:路径按第一级分组(如 /user/profile 属于 user 组),减少初始化负载。

2、初始化与路由加载(运行时)

  • 路由组加载:扫描 classpath 找到所有 IRouteGroup 实现类,加载路由信息到 Warehouse
  • 拦截器加载:加载并排序所有拦截器。
  • 按需加载:实际实现中按分组延迟加载,首次访问某分组时才加载。
    • Debug 模式或新版本安装时全量加载
    • Release 模式从 SP 缓存读取

3、 路由跳转流程

  • 路由查找:通过路径在 Warehouse.routes 中查找元数据。
  • 拦截器链:所有拦截器异步执行,通过 InterceptorCallback 控制流程,每个拦截器可中断流程。
  • 目标分发:根据路由类型执行不同操作(启动 Activity 或获取服务)。

4、拦截器链实现

  • 优先级排序:拦截器按 priority 排序,值越小优先级越高。
  • 递归执行:使用嵌套函数实现拦截器链的递归调用。
  • 异步支持:实际实现支持异步拦截器操作。

5、依赖注入实现

  • 运行时查找:根据类名拼接注入器类名。
  • 自动注入:注入器从 Intent 中提取参数并赋值给字段。
  • 类型转换:处理基本类型和自定义类型的转换。

6、服务发现实现

  • 接口映射:通过接口类名查找实现类的路由元数据。
  • 单例缓存:使用双重检查锁确保服务单例。
  • 延迟初始化:服务在首次访问时初始化。

三、完整的代码示例模拟ARouter全流程

下面我将通过一个完整的代码示例,贯穿 ARouter 的核心实现原理,包括注解处理、路由表生成、初始化流程、跳转逻辑、拦截器链、依赖注入和服务发现。

1、核心注解定义

这些注解在实际项目中会由 ARouter 库提供。

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 路由注解,标记可路由的 Activity/Service
 * @property path 路由路径
 * @property group 路由分组(可选)
 */
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Route(
    val path: String,
    val group: String = ""
)
​
/**
 * 自动注入注解,标记需要自动注入的字段
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class Autowired(
    val name: String = "" // 参数名称,默认为字段名
)
​
/**
 * 拦截器注解,标记路由拦截器
 * @property priority 优先级,值越小优先级越高
 */
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Interceptor(val priority: Int)

2、核心数据结构

路由元数据,存储路由相关信息,在实际项目中会由 ARouter 库提供。

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 路由元数据类型
 */
enum class RouteType {
    ACTIVITY,  // Activity 路由
    FRAGMENT,  // Fragment 路由
    PROVIDER   // 服务提供者
}
​
/**
 * 路由元数据类
 * @property path 路由路径
 * @property type 路由类型
 * @property clazz 目标类
 * @property group 路由分组
 */
data class RouteMeta(
    val path: String,
    val type: RouteType,
    val clazz: Class<*>,
    val group: String
)
​
/**
 * 路由仓库(存储所有路由信息)
 */
object Warehouse {
    // 路由表:路径 -> 路由元数据
    val routes = mutableMapOf<String, RouteMeta>()
    
    // 分组表:组名 -> 组内路由
    val groups = mutableMapOf<String, MutableList<RouteMeta>>()
    
    // 拦截器表:优先级 -> 拦截器类
    val interceptors = sortedMapOf<Int, Class<out IInterceptor>>()
    
    // 服务实例缓存:路径 -> 服务实例
    val providers = mutableMapOf<String, Any>()
    
    // 服务元数据表:接口类名 -> 路由元数据
    val providersIndex = mutableMapOf<String, RouteMeta>()
}

3、核心接口定义

这些接口定义了 ARouter 的核心行为,在实际项目中会由 ARouter 库提供。

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 拦截器接口
 */
interface IInterceptor {
    fun process(postcard: Postcard, callback: InterceptorCallback)
}
​
/**
 * 拦截器回调接口
 */
interface InterceptorCallback {
    fun onContinue(postcard: Postcard)
    fun onInterrupt(exception: Throwable)
}
​
/**
 * 服务提供者接口
 */
interface IProvider {
    fun init(context: Context)
}
​
/**
 * 路由信息载体(类似 Intent)
 */
class Postcard(val path: String) {
    // 跳转参数
    val extras = Bundle()
    
    // 添加参数
    fun withString(key: String, value: String): Postcard {
        extras.putString(key, value)
        return this
    }
    
    // 添加对象参数(实际实现会更复杂)
    fun withObject(key: String, value: Any): Postcard {
        extras.putSerializable(key, value as Serializable)
        return this
    }
}

4、模拟 APT 生成的代码

这些类在实际项目中由注解处理器在编译期生成。

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 模拟 APT 生成的用户模块路由组
 */
class ARouter$$Group$$user : IRouteGroup {
    override fun loadInto(routes: MutableMap<String, RouteMeta>) {
        routes["/user/profile"] = RouteMeta(
            path = "/user/profile",
            type = RouteType.ACTIVITY,
            clazz = UserProfileActivity::class.java,
            group = "user"
        )
        
        routes["/service/user"] = RouteMeta(
            path = "/service/user",
            type = RouteType.PROVIDER,
            clazz = UserServiceImpl::class.java,
            group = "user"
        )
    }
}
​
/**
 * 模拟 APT 生成的订单模块路由组
 */
class ARouter$$Group$$order : IRouteGroup {
    override fun loadInto(routes: MutableMap<String, RouteMeta>) {
        routes["/order/detail"] = RouteMeta(
            path = "/order/detail",
            type = RouteType.ACTIVITY,
            clazz = OrderDetailActivity::class.java,
            group = "order"
        )
    }
}
​
/**
 * 模拟 APT 生成的拦截器注册类
 */
class ARouter$$Interceptors : IInterceptorGroup {
    override fun loadInto(interceptors: MutableMap<Int, Class<out IInterceptor>>) {
        interceptors[10] = AuthInterceptor::class.java
        interceptors[20] = LoggingInterceptor::class.java
    }
}
​
/**
 * 模拟 APT 生成的自动注入类
 */
class UserProfileActivity$$Autowired : ISyringe {
    override fun inject(target: Any) {
        val activity = target as UserProfileActivity
        val extras = activity.intent?.extras ?: return
        
        if (extras.containsKey("userId")) {
            activity.userId = extras.getString("userId") ?: ""
        }
        
        if (extras.containsKey("userName")) {
            activity.userName = extras.getString("userName") ?: ""
        }
    }
}

5、路由核心实现

ARouter 的核心实现类,在实际项目中会由 ARouter 库提供。

代码语言:javascript
代码运行次数:0
运行
复制
object ARouter {
    private var initialized = false
    private lateinit var context: Context
    
    /**
     * 初始化 ARouter
     */
    fun init(context: Context) {
        this.context = context.applicationContext
        if (initialized) return
        
        // 1. 加载路由组
        loadRouteGroups()
        
        // 2. 加载拦截器
        loadInterceptors()
        
        initialized = true
    }
    
    /**
     * 加载路由组(模拟实现)
     */
    private fun loadRouteGroups() {
        // 在实际实现中,这里会扫描 classpath 找到所有 IRouteGroup 实现类
        val routeGroups = listOf(
            ARouter$$Group$$user(),
            ARouter$$Group$$order()
        )
        
        // 加载每个路由组
        routeGroups.forEach { group ->
            val groupMap = mutableMapOf<String, RouteMeta>()
            group.loadInto(groupMap)
            
            // 添加到仓库
            groupMap.values.forEach { meta ->
                Warehouse.routes[meta.path] = meta
                
                // 按分组存储
                val groupList = Warehouse.groups.getOrPut(meta.group) { mutableListOf() }
                groupList.add(meta)
                
                // 如果是服务提供者,添加到服务索引
                if (meta.type == RouteType.PROVIDER) {
                    meta.clazz.interfaces.forEach { interfaceClass ->
                        Warehouse.providersIndex[interfaceClass.name] = meta
                    }
                }
            }
        }
    }
    
    /**
     * 加载拦截器(模拟实现)
     */
    private fun loadInterceptors() {
        // 在实际实现中,这里会扫描 classpath 找到所有 IInterceptorGroup 实现类
        val interceptorGroup = ARouter$$Interceptors()
        val interceptors = mutableMapOf<Int, Class<out IInterceptor>>()
        interceptorGroup.loadInto(interceptors)
        
        // 添加到仓库(按优先级排序)
        Warehouse.interceptors.putAll(interceptors)
    }
    
    /**
     * 构建路由信息
     */
    fun build(path: String): Postcard {
        return Postcard(path)
    }
    
     /**
     * 执行路由跳转
     */
    fun navigation(postcard: Postcard) {
        // 1. 根据路径查找路由元数据
        val routeMeta = Warehouse.routes[postcard.path] 
            ?: throw RuntimeException("Route not found: ${postcard.path}")
        
        // 2. 处理拦截器
        processInterceptors(postcard) { success ->
            if (success) {
                // 3. 执行实际跳转
                when (routeMeta.type) {
                    RouteType.ACTIVITY -> startActivity(routeMeta, postcard)
                    RouteType.PROVIDER -> getProvider(routeMeta)
                    // 其他类型处理...
                }
            }
        }
    }
    
    /**
     * 处理拦截器链
     */
    private fun processInterceptors(
        postcard: Postcard, 
        callback: (Boolean) -> Unit
    ) {
        // 按优先级排序的拦截器列表
        val interceptors = Warehouse.interceptors.values.toList()
        var index = 0
        
        // 递归执行拦截器
        fun next() {
            if (index >= interceptors.size) {
                callback(true) // 所有拦截器通过
                return
            }
            
            val interceptorClass = interceptors[index++]
            try {
                val interceptor = interceptorClass.getDeclaredConstructor().newInstance()
                interceptor.process(postcard, object : InterceptorCallback {
                    override fun onContinue(nextPostcard: Postcard) {
                        next() // 继续下一个拦截器
                    }
                    
                    override fun onInterrupt(exception: Throwable) {
                        callback(false) // 被拦截
                    }
                })
            } catch (e: Exception) {
                // 处理异常
                next() // 继续下一个
            }
        }
        
        next() // 开始拦截器链
    }
    
    /**
     * 启动 Activity
     */
    private fun startActivity(meta: RouteMeta, postcard: Postcard) {
        val intent = Intent(context, meta.clazz).apply {
            putExtras(postcard.extras)
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }
        context.startActivity(intent)
    }
    
    /**
     * 获取服务提供者
     */
    fun <T> getProvider(meta: RouteMeta): T? {
        // 双重检查锁实现单例
        val provider = Warehouse.providers[meta.path]
        if (provider != null) return provider as T
        
        return synchronized(this) {
            Warehouse.providers[meta.path]?.let { return it as T }
            
            // 创建新实例
            val instance = meta.clazz.getDeclaredConstructor().newInstance()
            
            // 初始化服务
            (instance as? IProvider)?.init(context)
            
            // 缓存实例
            Warehouse.providers[meta.path] = instance
            instance as T
        }
    }
    
     /**
     * 通过接口类型获取服务
     */
    fun <T> navigation(service: Class<T>): T? {
        // 1. 查找服务实现类的路由元数据
        val meta = Warehouse.providersIndex[service.name] 
            ?: return null
        
        // 2. 获取服务实例
        return getProvider(meta)
    }
    
    /**
     * 依赖注入
     */
    fun inject(target: Any) {
        val className = target.javaClass.name + "$$Autowired"
        try {
            // 加载自动注入类
            val injector = Class.forName(className)
                .getDeclaredConstructor()
                .newInstance() as ISyringe
            
            // 执行注入
            injector.inject(target)
        } catch (e: Exception) {
            // 处理注入失败
        }
    }
}

6、业务代码示例

实际业务中使用 ARouter 的示例。

代码语言:javascript
代码运行次数:0
运行
复制
// 用户服务接口(公共模块)
interface UserService : IProvider {
    fun getUserInfo(userId: String): User
    fun isLoggedIn(): Boolean
}
​
// 用户信息数据类
data class User(val id: String, val name: String)
​
// 用户服务实现(用户模块)
@Route(path = "/service/user")
class UserServiceImpl : UserService {
    override fun init(context: Context) {
        // 服务初始化
    }
    
    override fun getUserInfo(userId: String): User {
        // 实际业务逻辑
        return User(userId, "KotlinUser")
    }
    
    override fun isLoggedIn() = true
}
​
// 用户详情页(用户模块)
@Route(path = "/user/profile")
class UserProfileActivity : AppCompatActivity() {
    @Autowired
    lateinit var userId: String
    
    @Autowired(name = "userName")
    lateinit var userName: String
    
    private val userService by lazy {
        ARouter.navigation(UserService::class.java)
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 依赖注入
        ARouter.inject(this)
        
        // 使用注入的参数
        Log.d("UserProfile", "User ID: $userId, Name: $userName")
        
        // 使用服务
        userService?.getUserInfo(userId)?.let { user ->
            Toast.makeText(this, "User: ${user.name}", Toast.LENGTH_SHORT).show()
        }
    }
}
​
// 订单详情页(订单模块)
@Route(path = "/order/detail")
class OrderDetailActivity : AppCompatActivity() {
    private val userService by lazy {
        ARouter.navigation(UserService::class.java)
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 跨模块获取用户信息
        val userId = intent.getStringExtra("userId") ?: ""
        userService?.getUserInfo(userId)?.let { user ->
            Log.d("OrderDetail", "Order for user: ${user.name}")
        }
    }
}
​
// 登录拦截器
@Interceptor(priority = 10)
class AuthInterceptor : IInterceptor {
    override fun process(postcard: Postcard, callback: InterceptorCallback) {
        if (postcard.path.startsWith("/user/") && !isLoggedIn()) {
            // 未登录,重定向到登录页
            callback.onInterrupt(RuntimeException("Auth required"))
            ARouter.build("/login").navigation()
        } else {
            // 已登录,继续流程
            callback.onContinue(postcard)
        }
    }
    
    private fun isLoggedIn(): Boolean {
        // 实际登录检查逻辑
        return false
    }
}
​
// 日志拦截器
@Interceptor(priority = 20)
class LoggingInterceptor : IInterceptor {
    override fun process(postcard: Postcard, callback: InterceptorCallback) {
        Log.d("ARouter", "Navigating to: ${postcard.path}")
        callback.onContinue(postcard)
    }
}

7、使用示例

代码语言:javascript
代码运行次数:0
运行
复制
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        
        // 初始化 ARouter
        ARouter.init(this)
        
        // 示例:跳转到用户详情页
        ARouter.build("/user/profile")
            .withString("userId", "123")
            .withString("userName", "KotlinUser")
            .navigation()
        
        // 示例:在订单模块获取用户服务
        val userService = ARouter.navigation(UserService::class.java)
        val user = userService?.getUserInfo("456")
    }
}

8、ARouter 工作流程总结

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * ARouter 完整工作流程:
 * 
 * 1. 编译期(APT 处理):
 *    - 扫描 @Route 注解,生成路由表(如 ARouter$$Group$$user)
 *    - 扫描 @Autowired 注解,生成注入类(如 UserProfileActivity$$Autowired)
 *    - 扫描 @Interceptor 注解,生成拦截器注册表
 * 
 * 2. 初始化阶段(应用启动时):
 *    - 加载所有路由组(loadRouteGroups)
 *    - 加载所有拦截器(loadInterceptors)
 *    - 构建路由仓库(Warehouse)
 * 
 * 3. 路由跳转流程:
 *    - 构建 Postcard 对象(携带路径和参数)
 *    - 在路由仓库中查找目标路由元数据
 *    - 执行拦截器链(按优先级顺序)
 *    - 根据路由类型执行实际跳转(启动 Activity 或获取服务)
 * 
 * 4. 依赖注入流程:
 *    - 在 Activity 中调用 ARouter.inject(this)
 *    - 加载并执行自动生成的注入类
 *    - 将 Intent 中的参数注入到 @Autowired 字段
 * 
 * 5. 服务发现流程:
 *    - 通过接口类型查找服务路由元数据
 *    - 使用双重检查锁创建或获取服务实例
 *    - 缓存服务实例提高后续访问性能
 * 
 * 6. 拦截器工作流程:
 *    - 按优先级排序拦截器
 *    - 递归执行拦截器链
 *    - 每个拦截器可以中断或继续流程
 *    - 支持全局拦截逻辑(如登录检查)
 */

四、总结

ARouter 通过编译期注解处理和运行时路由管理的结合,实现了高效的组件化解耦方案:

  • 编译期:APT 扫描注解并生成路由表、注入器和拦截器注册代码
  • 初始化:加载路由组和拦截器到内存仓库,按需加载减少启动耗时
  • 路由跳转:通过路径查找目标,经过拦截器链后执行实际跳转
  • 依赖注入:自动生成注入器类,实现参数自动填充
  • 服务发现:通过接口类型动态获取实现,双重检查锁保证单例

这种架构设计使 ARouter 能够:

  • 实现模块间完全解耦
  • 提供统一的路由管理
  • 支持灵活的拦截器机制
  • 保证高效的运行时性能
  • 简化模块间通信和服务调用

以上实现虽然进行了简化,但完整展示了 ARouter 的核心原理和设计思想。实际项目中,ARouter 还包含更多优化和高级特性,如多模块支持、动态路由注册、降级策略等。

五、典型应用场景

  • 组件化解耦:模块间通过路由通信,避免直接依赖
  • 统一登录拦截:在拦截器中检查登录状态,未登录时重定向至登录页
  • 动态路由配置:服务端下发路由路径,实现动态页面跳转规则
  • 跨模块数据获取:如用户模块暴露 UserService,订单模块直接调用查询用户信息

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、核心功能
    • 1、页面路由与跳转
    • 2、拦截器(Interceptor)
    • 3、服务发现与依赖注入
    • 4、动态注册与多模块支持
  • 二、实现原理
    • 1、注解处理与路由表生成(编译期)
    • 2、初始化与路由加载(运行时)
    • 3、 路由跳转流程
    • 4、拦截器链实现
    • 5、依赖注入实现
    • 6、服务发现实现
  • 三、完整的代码示例模拟ARouter全流程
    • 1、核心注解定义
    • 2、核心数据结构
    • 3、核心接口定义
    • 4、模拟 APT 生成的代码
    • 5、路由核心实现
    • 6、业务代码示例
    • 7、使用示例
    • 8、ARouter 工作流程总结
  • 四、总结
  • 五、典型应用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档