使用Jetpack Navigation如何在导航前检查DeepLink是否已定义?
优雅判断DeepLink是否可路由的方案
需求场景
在尝试通过DeepLink导航前,先判断该DeepLink是否已在导航图中定义,若未定义则执行其他路由逻辑。
现有方案分析
你当前的实现通过调用导航图的matchDeepLink方法判断,但该方法属于受限API,需要添加@SuppressLint("RestrictedApi")规避警告,存在依赖内部API的风险:
@SuppressLint("RestrictedApi") fun NavController.isDeepLinkDefined(deeplink: Uri, action: String, mimeType: String): Boolean { return graph.matchDeepLink(NavDeepLinkRequest(deeplink, action, mimeType)) != null }
更优雅的替代方案
方案1:使用公开API hasDeepLink(Navigation 2.4.0+)
从Jetpack Navigation 2.4.0版本开始,NavController提供了公开的hasDeepLink扩展方法,无需依赖内部API,直接使用即可:
fun NavController.isDeepLinkDefined(deeplink: Uri, action: String, mimeType: String): Boolean { val request = NavDeepLinkRequest.Builder .fromUri(deeplink) .setAction(action) .setMimeType(mimeType) .build() return hasDeepLink(request) }
该方法内部已封装DeepLink匹配逻辑,完全符合公开API使用规范,无需额外Lint抑制。
方案2:兼容旧版本的安全实现
如果项目仍使用低于2.4.0的Navigation版本,可通过反射安全调用内部方法,避免直接依赖受限API:
fun NavController.isDeepLinkDefined(deeplink: Uri, action: String, mimeType: String): Boolean { val request = NavDeepLinkRequest(deeplink, action, mimeType) return try { val matchMethod = NavGraph::class.java.getMethod("matchDeepLink", NavDeepLinkRequest::class.java) matchMethod.isAccessible = true matchMethod.invoke(graph, request) != null } catch (e: Exception) { // 反射失败时默认返回false,执行备选路由 false } }
这种方式通过反射间接调用内部方法,既避免了硬编码的Lint抑制,又在反射失败时提供了降级处理逻辑。
内容的提问来源于stack exchange,提问作者dazza5000
相关产品推荐
相关产品推荐

