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 自动注入参数,减少模板代码
相关推荐
Junerver1 天前
我写了一个 Compose Multiplatform 组件库,你可能会用到
kotlin·android jetpack
我命由我123452 天前
Jetpack Room - Room 查询返回列表无需判空、LIKE 关键字
android·java·开发语言·java-ee·android jetpack·android-studio·android runtime
QING6183 天前
Kotlin 日常开发常用语法糖整理 —— 速记
android·kotlin·android jetpack
我命由我123453 天前
Android 开发问题:EditText 控件的 android:imeOptions=“actionDone“ 属性不生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
我命由我123453 天前
Android 开发问题:获取到的 Android ID 发生了变化
android·java·开发语言·java-ee·android studio·android jetpack·android runtime
我命由我123454 天前
Android 开发问题:Unable to find explicit activity class
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
我命由我123454 天前
Android 开发问题:全局的主题颜色设置,导致 CheckBox 控件在勾选状态下不显示样式
android·java·开发语言·java-ee·intellij-idea·intellij idea·android jetpack
alexhilton6 天前
Android的Agent优先时代:构建时vs运行时
android·kotlin·android jetpack
我命由我123457 天前
Android 开发问题:View 的 getWidth、getHeight 方法返回的值都为 0
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
QING6187 天前
Kotlin 协程新手指南 —— 结构化并发
android·kotlin·android jetpack