InsertKoinIO / koin

Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
https://insert-koin.io
Apache License 2.0
9.08k stars 718 forks source link

Compose Multiplatform using koinNavViewModel() to create a ViewModel will cause a crash on Android #1926

Closed Reach2027 closed 2 months ago

Reach2027 commented 3 months ago

Describe the bug In the compose multiplatform project, using koinNavViewModel() to create a ViewModel will cause a crash on Android, it is normal on iOS and desktop.

FATAL EXCEPTION: main
Process: com.reach.kmp, PID: 6159
java.lang.NoSuchMethodError: No virtual method getArguments()Landroidx/core/bundle/Bundle; in class Landroidx/navigation/NavBackStackEntry; or its super classes (declaration of 'androidx.navigation.NavBackStackEntry' appears in /data/app/~~0V-y2iYYV0J5BlmEyyRcCQ==/com.reach.kmp-JhRe6IHzM29St0VX0yPN4A==/base.apk!classes16.dex)
at org.koin.viewmodel.CreationExtrasExtKt.defaultNavExtras(CreationExtrasExt.kt:16)
at com.reach.kmp.feature.bingwallpaper.BingWallpaperScreenKt.BingWallpaperRoute(BingWallpaperScreen.kt:213)
at com.reach.kmp.feature.bingwallpaper.BingWallpaperScreenKt.access$BingWallpaperRoute(BingWallpaperScreen.kt:1)
at com.reach.kmp.feature.bingwallpaper.ComposableSingletons$BingWallpaperScreenKt$lambda-1$1.invoke(BingWallpaperScreen.kt:56)
at com.reach.kmp.feature.bingwallpaper.ComposableSingletons$BingWallpaperScreenKt$lambda-1$1.invoke(BingWallpaperScreen.kt:55)

To Reproduce Launch android app

Expected behavior Create NavBackStackEntry ViewModel success on Android.

Koin module and version: koin-compose-viewmodel:4.0.0-RC1

Snippet or Sample project to help reproduce https://github.com/Reach2027/Kmp/blob/master/feature/bingwallpaper/src/commonMain/kotlin/com/reach/kmp/feature/bingwallpaper/BingWallpaperScreen.kt

line:62

kmbisset89 commented 2 months ago

@arnaudgiuliani I looked into this and saw that the class should have this field. I have to figure that this would be fixed by stabilization in the navigation library.

renaudmathieu commented 2 months ago

Able to reproduce on my side as well

sayah-y commented 2 months ago

It's mainly due to the fact that the Navigation component library was significantly refactored in recent version and the getArguments() method was removed from ViewModelStoreOwner.

public interface ViewModelStoreOwner {

    /**
     * The owned [ViewModelStore]
     */
    public val viewModelStore: ViewModelStore
}

But, koin continues to use it:

@OptIn(KoinInternalApi::class)
fun defaultNavExtras(viewModelStoreOwner: ViewModelStoreOwner): CreationExtras = when {
    viewModelStoreOwner is NavBackStackEntry && viewModelStoreOwner.arguments != null -> viewModelStoreOwner.arguments?.toExtras(viewModelStoreOwner) ?: CreationExtras.Empty
    viewModelStoreOwner is HasDefaultViewModelProviderFactory -> viewModelStoreOwner.defaultViewModelCreationExtras
    else -> CreationExtras.Empty
}

Actually, koin-compose-viewmodel:4.0.0-RC1 cannot be use with an updated Android project.

kmbisset89 commented 2 months ago

@sayah-y

I am looking at the documentation and the NavBackstackEntry still implements ViewModelStoreOwner and has the getArguments() function according to what I found here.

https://developer.android.com/reference/androidx/navigation/NavBackStackEntry

When I debugged the code the is NavBackstackEntry is true, is there a better place to pull documentation?

arnaudgiuliani commented 2 months ago

yes known issue on current jetbrains API

arnaudgiuliani commented 2 months ago

waiting for JB feedback

arnaudgiuliani commented 2 months ago

Solution found in this slack thread: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1725012875898249 Fixed in RC2