Kotlin 项目报 Implemented only in JetBrains fork 错误怎么办?
结论
崩溃发生在 rememberNavController() 内部,建议先检查 Navigation Compose 实际解析到的依赖及平台变体。现有代码和堆栈还不足以确定具体是哪个版本或配置导致了问题,也无法给出一个保证有效的版本号。
关键堆栈:
kotlin.NotImplementedError: Implemented only in JetBrains fork.
at androidx.navigation.compose.NavHostController_nonAndroidKt.rememberNavController(NavHostController.nonAndroid.kt:32)
Android 应用运行时进入了名为 nonAndroid 的实现路径。根据异常信息,可能是当前使用的 Navigation Compose 产物包含了不适用于这次 Android 调用的占位实现,需要通过依赖解析结果确认。
为什么先检查依赖
代码已导入 rememberNavController,并在 @Composable 函数中调用:
import androidx.navigation.compose.rememberNavController
val navController = rememberNavController()
这段调用本身没有明显错误。异常来自库内部,堆栈尚未执行到导航按钮或地图按钮的点击逻辑。
问题是在项目换到另一台电脑后出现的,值得比较两台机器实际使用的依赖、Gradle Wrapper 和构建配置。即使源码相同,动态版本、未提交的版本目录、本地仓库或依赖替换规则也可能使解析结果不同。这些目前都只是排查方向。
1. 比较两台电脑的依赖解析结果
如果应用模块名为 app,运行的是 debug 构建,可以在项目根目录执行:
./gradlew :app:dependencyInsight --dependency navigation-compose --configuration debugRuntimeClasspath
./gradlew :app:dependencyInsight --dependency navigation-compose --configuration debugCompileClasspath
Windows 下使用 gradlew.bat。如果模块名、构建类型或 product flavor 不同,需要替换任务路径和 configuration 名称。
重点比较:
- 最终选中的 Navigation Compose 依赖坐标和版本。
- 哪个直接依赖或传递依赖引入了它。
- 是否发生版本冲突、强制选择或 dependency substitution。
- 编译与运行时是否解析到了预期的 Android 变体。
需要查看更完整的依赖关系时,再执行:
./gradlew :app:dependencies --configuration debugRuntimeClasspath
如果原来的电脑仍能运行,保留其输出并逐项对比,通常比直接升级所有库更容易找到差异。
2. 检查 Navigation Compose 的声明位置与来源
如果这是普通 Android 应用,检查应用模块是否使用了预期的 AndroidX Navigation Compose 依赖。下面仅展示声明形式,版本占位符必须替换为项目确认兼容的固定版本:
dependencies {
implementation("androidx.navigation:navigation-compose:<已确认兼容的固定版本>")
}
如果项目通过 libs.versions.toml 引用依赖,应修改对应的版本或 library 声明,避免重复添加依赖。
还要检查模块构建脚本、版本目录和 settings.gradle.kts 中是否存在:
- AndroidX 与 JetBrains 提供的 Navigation 相关依赖混用。
- 手动添加的 JAR、本地 Maven 产物或依赖替换规则。
- 强制指定 artifact、classifier 或平台属性的配置。
+、版本范围等会让不同时间解析出不同结果的版本声明。
如果实际是 Kotlin Multiplatform 项目,还需要检查 source set 和 Android target 的依赖配置。不能仅凭依赖名称中出现 JetBrains 就判断它有问题,也不要只看 androidx.navigation.compose 包名判断依赖来源。
3. 对齐可复现的构建环境
在两台电脑上执行:
./gradlew --version
比较 Gradle 和 JVM 信息,确认使用的是同一提交中的 Gradle Wrapper、构建脚本和版本目录。同时检查 Android Studio 配置的 Gradle JDK 是否与预期一致。
错误信息中的 JetBrains fork 不能直接证明需要更换 IDE 或安装某种 Kotlin 分支。先找到抛出异常的依赖产物,再决定调整哪项配置。
确认并修正依赖后,重新构建:
./gradlew :app:clean :app:assembleDebug
如果有证据表明本地依赖缓存与预期不一致,再刷新依赖:
./gradlew :app:assembleDebug --refresh-dependencies
刷新缓存不会修复错误的依赖声明。使用动态版本时,刷新还可能改变解析结果,因此应先记录当前依赖信息。
4. 单独处理代码中的 TODO()
地图按钮中还有一处会抛出 NotImplementedError 的代码:
onClick = { TODO() }
点击按钮时会触发另一处异常,应将其替换为实际功能,或暂时禁用按钮。它与当前堆栈指向的 rememberNavController() 崩溃是两个独立问题。
如果仍然报错,需要哪些信息
继续定位需要应用模块的 build.gradle.kts 或 build.gradle、相关版本目录、仓库与插件配置,以及 dependencyInsight 的输出。现有材料不包含这些信息,还无法确认具体冲突项或修复版本。
修复后应重新安装生成的 APK,确认页面可以创建导航控制器,再测试导航和地图按钮。如果仍然崩溃,从新堆栈中的首个异常位置继续排查。
备注:内容仅供参考。
