I had this simple viewmodel provider factory code (borrowed from one of Google’s code samples), which happily obliged and compiled perfectly…
fun <VM : ViewModel> viewModelProviderFactoryOf(
create: () -> VM
): ViewModelProvider.Factory = SimpleFactory(create)
private class SimpleFactory<VM : ViewModel>(
private val create: () -> VM
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val vm = create()
if (modelClass.isInstance(vm)) {
@Suppress("UNCHECKED_CAST")
return vm as T
}
throw IllegalArgumentException("Can not create ViewModel for class: $modelClass")
}
}
… Until i introduced this library:
implementation "androidx.navigation:navigation-compose:2.5.0-rc02"
Now all of a sudden compilation fails with:
Inheritance from an interface with ‘@JvmDefault’ members is only allowed with -Xjvm-default option
(error pointing to : ViewModelProvider.Factory )
Why? What did navigation bring in with it? (I did confirm 100% it’s the navigation lib causing it, remove it, and the error is gone)
Note: Q is not about how to solve it, compiler suggests it clearly, adding these args – freeCompilerArgs += "-Xjvm-default=all". The Q is about why this is happening.
4
Answers
OK, found it. The problem is that bringing in compose navigation, version 2.5.0-rc also updates androidx.lifecycle to 2.5.0-rc (from, in my case, 2.3.0), and in there, they changed the Factory interface by adding a method with implementation (and also adding implementation to the existing method in the interface).
Compare:
Factory implementation before 2.5.0:
Note one method, create, without implementation.
Here is the rewrite they did in 2.5.0
So that explains it, this interface is now a default implementation interface, and to inherit from it, need to add the compiler args, as suggested by the compiler (freeCompilerArgs += "-Xjvm-default=all").
We encountered this also when we added compose libraries. We solved it by adding the
xjvm-default
option to our gradle file.first, upgrade all of your fragment and activity dependencies to
1.5.0
and your lifecycle dependencies to2.5.0
. by doing so, your activities and fragments can handle thecreationExtras
part without requiring you to do anything. then in your factory method, replace this line:and you are good to go. source: These extras are provided automatically by your Activity or Fragment when using Activity 1.5.0 and Fragment 1.5.0, respectively.
this code worked for me