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. 初始化

ApplicationonCreate 中:

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 自动注入参数,减少模板代码
相关推荐
杉氧2 天前
Framework 补完计划 (2):BufferQueue 与 SurfaceFlinger —— 像素的跨进程“接力赛”
android·架构·android jetpack
我命由我123452 天前
Android 开发问题:ClickableSpan 的点击事件没有生效
java·java-ee·android studio·android jetpack·android-studio·android runtime
我命由我123453 天前
Android 构建项目问题:XML 片段出错,com.ctc.wstx.exc.WstxUnexpectedCharException
android·xml·android studio·android jetpack·android-studio·android runtime
杉氧5 天前
跨平台资源管理:一套代码如何搞定 Android、iOS 和 Web 的图片与多语言?
android·架构·android jetpack
杉氧6 天前
兼容与共生:如何在旧项目中优雅地引入 Compose?
android·架构·android jetpack
杉氧6 天前
性能优化实战:如何定位冗余重组并榨干 Compose 的每一帧性能?
android·架构·android jetpack
alexhilton6 天前
将应用迁移到Navigation 3:痛点、加班和紧急修复
android·kotlin·android jetpack
杉氧7 天前
Navigation Compose 深度实践:如何优雅地串联起你的全栈 App?
android·架构·android jetpack
黄林晴7 天前
Room 3.0 正式发布!包名彻底重构,KMP 成为核心主线
android·android jetpack
杉氧8 天前
Compose 时代的 MVI 架构:如何用单向数据流驱动复杂 UI?
android·架构·android jetpack