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 自动注入参数,减少模板代码
相关推荐
ljt272496066114 小时前
Compose笔记(七十七)--视频录制
笔记·android jetpack
ljt272496066121 小时前
Compose笔记(七十六)--拍照预览
笔记·android jetpack
alexhilton2 天前
Jetpack Compose元球边缘效果
android·kotlin·android jetpack
阿巴斯甜2 天前
Navigation中,怎么用这个app:launchSingleTop="true"
android jetpack
阿巴斯甜2 天前
Android 中Navigation的使用
android jetpack
simplepeng6 天前
再见 PredictiveBackHandler:如何迁移到 Compose 中的新导航事件
android jetpack
alexhilton6 天前
在Compose中用Shader实现透明的粘稠元球效果
android·kotlin·android jetpack
ljt27249606619 天前
Compose笔记(七十四)--BlurMaskFilter
笔记·android jetpack
ljt27249606619 天前
Compose笔记(七十五)--withFrameNanos
笔记·android jetpack