Router 模块是基于注解的页面路由框架,提供了 Android 应用内的页面跳转、参数传递、拦截器机制和深链接支持。该模块采用编译时代码生成的方式,实现了高性能的路由分发机制。
/test)weparty://test/path)object Router {
// 构建路由请求
fun build(ctx: Context, path: String, fm: FragmentManager? = null): UriRequest
// 启动路由
fun startUri(request: UriRequest)
// 获取路由实例
fun <T> getRouterInstance(path: String): T?
// 绑定参数
fun bind(obj: Any)
// 获取深链接
fun getDeepLink(path: String): String
}
@RouterUri(
path: Array<String> = [], // 路由路径
interceptors: Array<KClass<*>> = [], // 拦截器列表
desc: String = "Empty description" // 描述信息
)
@BindExtra(
name: String // 参数名称
)
abstract class UriHandler {
abstract fun canHandle(request: UriRequest): Boolean
abstract fun handle(request: UriRequest)
// 内部调用链,包含拦截器处理
fun handleInner(request: UriRequest)
}
class UriRequest(
val context: Context,
val path: String,
val fragmentManager: FragmentManager?
) {
// 添加参数
fun putExtra(key: String, value: Any): UriRequest
// 启动路由
fun start()
}
// 注册路由
@RouterUri(path = ["/test"], interceptors = [TestUriInterceptor::class])
class TestRouterBindActivity : AppCompatActivity() {
@BindExtra(name = "extra_test")
var extraTest: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Router.bind(this) // 必须手动调用参数绑定
}
}
// 跳转调用
Router.build(context, "/test")
.putExtra("extra_test", "测试参数")
.start()
// scheme + host 路由
@RouterUri(
scheme = "weparty",
host = "test",
interceptors = [TestUriInterceptor::class]
)
class TestUriHandler : UriHandler() {
@BindExtra(name = "extra_test")
var extraTest: String? = null // 自动绑定,无需调用bind
override fun canHandle(request: UriRequest): Boolean {
return true
}
override fun handle(request: UriRequest) {
// 处理路由逻辑
}
}
// 跳转调用
Router.build(context, "weparty://test")
.putExtra("extra_test", "测试参数")
.start()
@RouterUri(
regex = "http(s)?://(.*\\.)?(weparty)\\.(com|info|cn).*",
priority = 2 // 数字越大优先级越高
)
class WebViewActivity : AppCompatActivity()
// 匹配调用
Router.build(context, "https://weparty.com/test")
.start()
class TestUriInterceptor : UriInterceptor {
override fun intercept(chain: UriInterceptor.Chain) {
val request = chain.request()
// 可以修改请求参数
// val newRequest = request.newBuilder().putExtra("key", "value").build()
// 继续执行
chain.proceed(request)
// 或者终止执行
// chain.abort()
}
}
@RouterUri(path = ["/bind_fragment"])
class BindFragment : Fragment() {
@BindExtra(name = "extra_test")
var extraTest: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Router.bind(this)
}
}
// 获取Fragment实例
val fragment = Router.getRouterInstance<Fragment>("/bind_fragment")
<!-- AndroidManifest.xml -->
<activity
android:name="com.adealink.frame.router.RouterDeepLinkActivity"
android:configChanges="keyboardHidden|orientation|screenSize">
<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:scheme="weparty" />
</intent-filter>
</activity>
# 触发深链接测试
adb shell am start -W -a android.intent.action.VIEW -d "weparty://test" com.your.package
// 为带@RouterUri的类生成
class TestActivity_IRouterInit : IRouterInit {
override val pathToClazzMap = mapOf("/test" to TestActivity::class.java)
}
// 为带@BindExtra的类生成
class TestActivity_IBinder : IBinder {
override fun bind(obj: Any) {
if (obj is TestActivity) {
obj.extraTest = obj.intent.getStringExtra("extra_test")
}
}
}
androidx.core.ktx - Android核心扩展androidx.appcompat - AppCompat支持frame:spi - 服务发现机制frame:base - 基础框架router-annotation - 注解定义// 应用模块
implementation "com.wenext.android:frame-router-api:6.0.0"
kapt "com.wenext.android:frame-router-compiler:6.0.0"
// 或在公共依赖中
api "com.wenext.android:frame-router-api:6.0.0"
Router.bind(this),UriHandler自动绑定getRouterInstance()返回的实例,避免内存泄漏