terrakok / Cicerone

🚦 Cicerone is a lightweight library that makes the navigation in an Android app easy.
Other
2.58k stars 218 forks source link

IllegalArgumentException while using Kotlin and pass only one parameter to router.navigateTo() #73

Closed badadin closed 6 years ago

badadin commented 6 years ago

If I use router.navigateTo() without passing data as a second parameter like this: App.INSTANCE.router.navigateTo(SCREEN_NAME) the app crashes with IllegalArgumentException. Part of stacktrace:

Process: com.example.etmkotlin, PID: 4753
    java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter data
        at com.example.etmkotlin.activities.MainActivity$navigator$1.createFragment(MainActivity.kt)
        at ru.terrakok.cicerone.android.SupportFragmentNavigator.forward(SupportFragmentNavigator.java:107)
        at ru.terrakok.cicerone.android.SupportFragmentNavigator.applyCommand(SupportFragmentNavigator.java:91)
        at ru.terrakok.cicerone.android.SupportFragmentNavigator.applyCommands(SupportFragmentNavigator.java:71)
        at ru.terrakok.cicerone.CommandBuffer.executeCommands(CommandBuffer.java:42)
        at ru.terrakok.cicerone.BaseRouter.executeCommands(BaseRouter.java:30)
        at ru.terrakok.cicerone.Router.navigateTo(Router.java:83)
        at ru.terrakok.cicerone.Router.navigateTo(Router.java:73)
        at com.example.etmkotlin.activities.MainActivity$override.openScreen(MainActivity.kt:107)
...

Part of Router.java:

/**
     * Open new screen and add it to the screens chain.
     *
     * @param screenKey screen key
     */
    public void navigateTo(String screenKey) {
        navigateTo(screenKey, null);
    }

    /**
     * Open new screen and add it to screens chain.
     *
     * @param screenKey screen key
     * @param data      initialisation parameters for the new screen
     */
    public void navigateTo(String screenKey, Object data) {
        executeCommands(new Forward(screenKey, data));
    }

So if the data is null it will crash. But if I pass some data for example: App.INSTANCE.router.navigateTo(SCREEN_NAME, "123") everything wotks great.

terrakok commented 6 years ago

Show your navigator. P.S.: and update Cicerone version :smile:

badadin commented 6 years ago

I have the last version of Cicerone at this moment (3.0.0) Here is my Navigator (just copied example from https://habr.com/company/mobileup/blog/314838/) and modified it):

private val navigator = object : SupportFragmentNavigator(supportFragmentManager, R.id.fragmentContainer) {
        override fun createFragment(screenKey: String, data: Any): Fragment? {
            return when (screenKey) {
                CHART_SCREEN -> ChartFragment.getInstance()
                CALENDAR_SCREEN -> CalendarFragment.getInstance()
                else -> null
            }
        }

        override fun showSystemMessage(message: String) {
            Toast.makeText(this@MainActivity, message, Toast.LENGTH_SHORT).show()
        }

        override fun exit() {
            finish()
        }
    }
yurimachioni commented 6 years ago

You are trying to navigate to the screen without passing a parameter, so you must allow the parameter to be null. Just make your data parameter optional:

override fun createFragment(screenKey: String, data: Any?): Fragment? {

badadin commented 6 years ago

You are trying to navigate to the screen without passing a parameter, so you must allow the parameter to be null. Just make your data parameter optional:

override fun createFragment(screenKey: String, data: Any?): Fragment? {

Exactly! Thank you very much! Вот я тупой :)