非法参数异常:savedInstanceState被指定为非空,但为空。

40

当我启动我的MainActivity时,我遇到了一个奇怪的错误:

06-16 16:01:05.193 2083-2083/? E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.android.example.github, PID: 2083
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.example.github/com.android.example.github.ui.MainActivity}: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2666)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727)
            at android.app.ActivityThread.-wrap12(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1478)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:154)
            at android.app.ActivityThread.main(ActivityThread.java:6121)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
          Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
            at com.android.example.github.injection.AppInjector$init$1.onActivityCreated(AppInjector.kt)
            at android.app.Application.dispatchActivityCreated(Application.java:197)
            at android.app.Activity.onCreate(Activity.java:961)
            at android.support.v4.app.BaseFragmentActivityGingerbread.onCreate(BaseFragmentActivityGingerbread.java:54)
            at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:319)
            at com.android.example.github.ui.MainActivity.onCreate(MainActivity.kt:20)
            at android.app.Activity.performCreate(Activity.java:6682)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727) 
            at android.app.ActivityThread.-wrap12(ActivityThread.java) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1478) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:154) 
            at android.app.ActivityThread.main(ActivityThread.java:6121) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779

这是我的 MainActivity 类:

class MainActivity : LifecycleActivity(), HasSupportFragmentInjector {

    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
        @Inject set

    lateinit var navigationController: NavigationController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        if (savedInstanceState == null) {
            navigationController.navigateToSearch()
        }
    }

    override fun supportFragmentInjector(): AndroidInjector<Fragment> {
        return dispatchingAndroidInjector
    }

}

出错信息显示,参数savedInstanceState被指定为非空但它实际上是可空的(savedInstanceState: Bundle?),并且源代码中onCreate()方法被标记为@Nullable,因此它会出现空指针异常。

在我的其他Kotlin项目中没有遇到过这个错误。我正在使用Kotlin版本1.1.2-5,并且在1.1.2-3中也遇到了同样的错误。


1
我有同样的问题。AppInjector上出了什么问题,你能提供建议吗? - Ramki Anba
7个回答

70

我曾经遇到过完全相同的问题,你需要在这里使用可空类型:

override fun onCreatePreferences(bundle: Bundle?, s: String?) {}

1
如果我无法更改此定义怎么办?例如,SDK库函数! - Kishore Jethava
8
谢谢!我的 DialogFragments(从 Android Studio 中从 Java 转换为 Kotlin)一直崩溃,只是在 onCreateDialog(savedInstanceState: Bundle?): Dialog 方法中的 Bundle 参数后加上一个问号就解决了问题! - Lucas P.
似乎这改变了继承函数的签名。我确认它能够正常运行,没有编译器错误。除此之外,我们重写一个函数时还有哪些方法可以改变函数的签名呢? - Michael Osofsky

19

问题在于AppInjector。我像你一样使用了Google的GitHubBrowser示例,并遇到了同样的错误。我将代码复制到我的项目中,并让Android Studio将其转换为Kotlin。但它没有正确指定savedInstanceState参数的可空性,这就是导致崩溃的原因。只需像下面的代码一样将其设置为可选项即可解决。

object AppInjector {
    fun init(app: App) {
        DaggerAppComponent.builder().application(app)
                .build().inject(app)
        app
                .registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
                    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                        handleActivity(activity)
                    }

                    override fun onActivityStarted(activity: Activity) {

                    }

                    override fun onActivityResumed(activity: Activity) {

                    }

                    override fun onActivityPaused(activity: Activity) {

                    }

                    override fun onActivityStopped(activity: Activity) {

                    }

                    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

                    }

                    override fun onActivityDestroyed(activity: Activity) {

                    }
                })
    }

    private fun handleActivity(activity: Activity) {
        if (activity is HasSupportFragmentInjector) {
            AndroidInjection.inject(activity)
        }
        (activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(
                object : FragmentManager.FragmentLifecycleCallbacks() {
                    override fun onFragmentCreated(fm: FragmentManager?, f: Fragment?,
                                                   savedInstanceState: Bundle?) {
                        if (f is Injectable) {
                            AndroidSupportInjection.inject(f)
                        }
                    }
                }, true)
    }
}

13

您可以使用空值合并运算符?:。只有当savedInstanceState@NonNull时,它才会传递给super.onCreate方法,否则如果为null,则会传递一个空的Bundle()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState?: Bundle())
}

1
感谢您添加答案!您介意解释一下您的解决方案中正在做什么吗? - Jack Moody

11

看起来问题不在onCreate方法中。建议查看com.android.example.github.injection.AppInjector$init$1.onActivityCreated(AppInjector.kt)。我无法确定它是否是一个自动生成的类,但这应该能给您下一步做什么的想法。


2
正如@mcassiano指出的那样,问题似乎不在你的onCreate方法中,而是在onActivityCreated中。有两个想法:
- 由于库等正在过渡期,现在您可能需要手动覆盖片段中的onActivityCreated并明确将Bundle标记为可为空:(savedInstanceState: Bundle?)。您不应该这样做,但手动设置空值可能会有所帮助。 - 我注意到崩溃一直延伸到BaseFragmentActivityGingerbread - 这是使用LifecycleActivity的结果吗?或者您的项目中是否有其他旧的、过时的依赖项?

0
如果其他方法都不起作用,你可以这样传递一个空的Bundle:
if (savedInstanceState == null)
    savedInstanceState = new Bundle();
super.onCreate(savedInstanceState);

或者如果你总是想要一个空的 bundle,那么只需:

super.onCreate(new Bundle());

可能不太好看,但是能用。


0
你知道在函数 super.onCreate 内部看起来像是 public void onCreate(Bundle savedInstanceState) ,这个 savedInstanceState 不能为 Null,而且可能会调用其他函数。在我的情况下,super.onCreate 连接到了 onCreatePreferences 函数,然后我解决了这个问题,以下是代码:
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {

    addPreferencesFromResource(R.xml.preferences_pomodoro)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState?:Bundle.EMPTY)

    if (context != null) {
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context!!)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接