ARouter的使用

一、基础使用(必须会)

一个用于 Android 组件化开发的路由框架,主要解决:

  • 跨组件跳转
  • 组件间通信
  • 解耦

简单说,就是统一管理所有页面跳转,让组件之间可以互相调用。

1. 添加依赖

项目级 build.gradle

gradle

arduino 复制代码
buildscript {
    dependencies {
        classpath "com.alibaba:arouter-register:1.0.2"
    }
}

模块级 build.gradle

gradle

javascript 复制代码
plugins {
    // 必须添加,用于注解处理器
    id 'kotlin-kapt'
}

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
               // 必须配置,用于区分不同模块
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }
}

dependencies {
    // ARouter 核心库 
    implementation 'com.alibaba:arouter-api:1.5.2' 
    // 注解处理器,用于生成路由表 
    kapt 'com.alibaba:arouter-compiler:1.5.2'
}

2. 初始化

在 Application 的 onCreate 中:

kotlin

scss 复制代码
if (BuildConfig.DEBUG) {
    ARouter.openLog()
    ARouter.openDebug()
}
// 初始化 ARouter
ARouter.init(this)
2.1 核心注解详解

@Route 注解

用于标记可路由的页面、服务等。

kotlin

ini 复制代码
@Route(
    path = "/video/video_fragment", // 必须,唯一标识
    group = "video", // 可选,分组,默认为path的第一个/后的部分
    name = "视频页面", // 可选,描述
    extras = Consts.USER_LOGIN // 可选,用于拦截器判断
)
class VideoFragment : Fragment() { ... }

3. 页面跳转

3.1 基础跳转

目标页面添加注解:

kotlin

kotlin 复制代码
@Route(path = "/video/video_fragment")
class VideoFragment : Fragment() { ... }

发起跳转:

kotlin

scss 复制代码
ARouter.getInstance()
    .build("/video/video_fragment")// 目标路径
    .navigation()// 执行跳转

3.2 带参数跳转

kotlin

vbscript 复制代码
ARouter.getInstance()
    .build("/video/video_fragment")
    .withInt("id", 123)
    .withString("name", "张三")
    .withParcelable("user", User())// 自定义对象必须实现 Parcelable
    .navigation()
3.3 接收参数

kotlin

kotlin 复制代码
@Route(path = "/video/video_fragment")
class VideoFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val id = arguments?.getInt("id")
        val name = arguments?.getString("name")
    }
}
4. 结果返回

kotlin

kotlin 复制代码
ARouter.getInstance()
    .build("/video/video_fragment")
    .navigation(this, 100) // 100是requestCode

// 在 onActivityResult 中接收
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 100 && resultCode == Activity.RESULT_OK) {
        // 处理结果
    }
}
5. 带回调的跳转

kotlin

kotlin 复制代码
ARouter.getInstance()
    .build("/video/video_fragment")
    .navigation(this, object : NavigationCallback {
        override fun onFound(postcard: Postcard?) {
            // 找到了路由
        }

        override fun onLost(postcard: Postcard?) {
            // 找不到路由
        }

        override fun onArrival(postcard: Postcard?) {
            // 跳转成功
        }

        override fun onInterrupt(postcard: Postcard?) {
            // 被拦截器中断
        }
    })

二、参数传递详解

1. 基本数据类型

kotlin

vbscript 复制代码
.withInt("id", 123)
.withLong("time", System.currentTimeMillis())
.withString("name", "张三")
.withBoolean("isVip", true)
.withFloat("score", 95.5f)
.withDouble("price", 199.99)

2. 数组和集合

kotlin

less 复制代码
.withIntArray("ids", intArrayOf(1, 2, 3))
.withStringArray("names", arrayOf("张三", "李四"))
.withStringArrayList("list", arrayListOf("a", "b", "c"))

3. 自定义对象

必须实现 Parcelable 接口:

kotlin

less 复制代码
@Parcelize
data class User(val id: Int, val name: String) : Parcelable

// 传递
.withParcelable("user", User(1, "张三"))
.withParcelableArrayList("users", arrayListOf(User(1, "张三"), User(2, "李四")))

三、高级功能(进阶必备)

1. 拦截器(Interceptor)

用于统一处理跳转前的逻辑,比如登录拦截。

定义拦截器:

kotlin

kotlin 复制代码
@Interceptor(
    priority = 8, // 优先级,数字越小优先级越高
    name = "登录拦截器" // 描述
)
class LoginInterceptor : IInterceptor {
    override fun process(postcard: Postcard, callback: InterceptorCallback) {
        // 获取目标页面的 extras
        val extras = postcard.extras

        // 判断是否需要登录
        if (extras and Consts.USER_LOGIN != 0) {
            if (isLogin()) {
                // 已登录,继续跳转
                callback.onContinue(postcard)
            } else {
                // 未登录,跳转到登录页
                ARouter.getInstance().build("/user/login").navigation()
                // 中断当前跳转
                callback.onInterrupt(null)
            }
        } else {
            // 不需要登录,继续跳转
            callback.onContinue(postcard)
        }
    }

    override fun init(context: Context?) {
        // 初始化工作
    }
}

使用拦截器:在目标页面的注解中添加拦截器:

kotlin

kotlin 复制代码
@Route(path = "/video/video_fragment", extras = Consts.USER_LOGIN)
class VideoFragment : Fragment() { ... }

2. 降级策略(DegradeService)

当路由找不到时的处理逻辑。

实现降级服务:

kotlin

kotlin 复制代码
@Route(path = "/degrade/service")
class DegradeServiceImpl : DegradeService {
    override fun onLost(context: Context?, postcard: Postcard?) {
        // 路由找不到时的处理,比如跳转到错误页
        Toast.makeText(context, "页面不存在", Toast.LENGTH_SHORT).show()
    }
}

3. PathReplaceService(路径替换)

kotlin

kotlin 复制代码
@Route(path = "/replace/service")
class PathReplaceServiceImpl : PathReplaceService {
    override fun forString(path: String): String {
        // 替换路径,比如兼容旧版本路径
        return if (path == "/old/video") "/video/video_fragment" else path
    }

    override fun forUri(uri: Uri): Uri {
        return uri
    }
}

4. 依赖注入(Autowired)

自动注入参数,无需手动 getIntent() 或 getArguments()。

目标页面:

kotlin

less 复制代码
@Route(path = "/video/video_fragment")
class VideoFragment : Fragment() {
    @Autowired(name = "id") // name 对应传递的 key
    @JvmField // 必须添加,否则会报错
    var userId: Int = 0

    @Autowired // 如果变量名和 key 一致,可以省略 name
    @JvmField
    var userName: String? = null

    @Autowired(required = false) // 非必须参数
    @JvmField
    var isVip: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ARouter.getInstance().inject(this) // 必须调用,否则注入失败
    }
}

发起跳转:

kotlin

vbscript 复制代码
ARouter.getInstance()
    .build("/video/video_fragment")
    .withInt("id", 123)
    .withInt("isVip", true)
    .withString("userName", "张三")
    .navigation()

5. Fragment 跳转

kotlin

scss 复制代码
val fragment = ARouter.getInstance().build("/video/video_fragment").navigation() as Fragment
supportFragmentManager.beginTransaction()
    .replace(R.id.container, fragment)
    .commit()

6. URI 跳转

xml

ini 复制代码
<activity
    android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="myapp.com"
            android:path="/video"
            android:scheme="app" />
    </intent-filter>
</activity>

跳转:

kotlin

scss 复制代码
val uri = Uri.parse("app://myapp.com/video?id=123&name=张三")
ARouter.getInstance().build(uri).navigation()

四、总结

功能 用法 优点
基础跳转 build(path).navigation() 简单、统一
参数传递 withXXX() 类型安全
结果返回 navigation(context, requestCode) 标准
拦截器 @Interceptor 统一处理登录、权限等
降级策略 DegradeService 优雅处理路由丢失
依赖注入 @Autowired 自动注入参数,减少模板代码
相关推荐
alexhilton44 分钟前
模块化Jetpack Compose架构
android·kotlin·android jetpack
hai_android3 小时前
InputStage 责任链核心执行流程
android·android studio·android jetpack
传奇开心果编程1 天前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程2 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程2 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
天空之城--5 天前
Android一周动态:Android 18首次官宣、Compose Material3 1.4转正(5趋势+5资讯)
android·人工智能·flutter·架构·android jetpack
传奇开心果编程5 天前
【现代声明式UI学与练】第1课 从命令式UI到声明式UI
学习·flutter·ui·swiftui·react·android jetpack
传奇开心果编程8 天前
【用案例学Material 3 Expressive】第1课:从一封邮件开始,感受安卓设计新语言的表现力
android·学习·ui·kotlin·android jetpack
传奇开心果编程9 天前
【Jetpack Compose进阶学与练】第14课:系列收尾复习总结;Compose项目常见坑点汇总;学习路线与后续学习方向
android·学习·ui·kotlin·android jetpack
hai_android9 天前
子 View 被压小时,如何向父容器"告状"?——MEASURED_STATE_TOO_SMALL 向上传递机制
android·kotlin·android jetpack