为何出现“继承含@JvmDefault成员的接口需-Xjvm-default选项”错误?如何修复?
解决ViewModelFactory实现接口时的@JvmDefault编译错误
错误原因
ViewModelProvider.Factory接口在新版AndroidX ViewModel库中新增了带@JvmDefault注解的默认方法,Kotlin编译器默认不允许直接继承这类接口,因此触发该编译错误。
解决方案
方案一:开启Kotlin编译的-Xjvm-default选项
在模块级的build.gradle(或build.gradle.kts)中添加编译参数,允许继承带有@JvmDefault成员的接口:
Groovy版本(build.gradle)
android { kotlinOptions { freeCompilerArgs += ["-Xjvm-default=all"] } }
Kotlin DSL版本(build.gradle.kts)
android { kotlinOptions { freeCompilerArgs += "-Xjvm-default=all" } }
添加后同步项目,即可正常编译你原有Factory类的代码。
方案二:改用AndroidX提供的抽象ViewModelFactory类
避免手动处理@JvmDefault的兼容问题,直接继承AndroidX封装好的AbstractSavedStateViewModelFactory抽象类:
class FavDishViewModel( private val repository: FavDishRepository ) : ViewModel() { fun insert(dish: FavDish) = viewModelScope.launch { repository.insertFavDishData(dish) } } class FavDishViewModelFactory( private val repository: FavDishRepository, owner: SavedStateRegistryOwner, defaultArgs: Bundle? = null ) : AbstractSavedStateViewModelFactory(owner, defaultArgs) { override fun <T : ViewModel> create( key: String, modelClass: Class<T>, handle: SavedStateHandle ): T { if (modelClass.isAssignableFrom(FavDishViewModel::class.java)) { @Suppress("UNCHECKED_CAST") return FavDishViewModel(repository) as T } throw IllegalArgumentException("Unknown ViewModel Class") } }
方案三:简化Factory创建(无需单独写类)
如果不需要复用Factory类,可以直接在创建ViewModel时用匿名内部类或lambda简化实现:
// 在Activity/Fragment中创建ViewModel val viewModel = ViewModelProvider(this, object : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { return FavDishViewModel(repository) as T } })[FavDishViewModel::class.java]
若使用较新的ViewModel库(依赖版本≥2.5.0),还可以用更简洁的写法:
val viewModel = viewModel { FavDishViewModel(repository) }
内容的提问来源于stack exchange,提问作者Aj Catindig
相关产品推荐
相关产品推荐

