getIntent().getExtras() 有时会在 Activity 中崩溃

Day*_*Day 5 crash android android-intent android-activity

我用一些额外的内容启动一个 Intent,并在 Activity 的中读取传递的额外内容onCreate

class MyActivity : AppCompatActivity() {

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

        val extras: Bundle? = intent.extras // <-- crash
        val someInt = extras?.getInt(EXTRA_SOME_INT, -1) ?: -1

        // ...
    }

    companion object {

        const val EXTRA_SOME_INT = "someInt"

        fun createIntent(context: Context, someInt: Int) =
            Intent(context, MyActivity::class.java).apply {
                putExtra(EXTRA_SOME_INT, someInt)
            }
    }
}

// Activity started like this:
fun startMyActivity(context: Context) {
    context.startActivity(MyActivity.createIntent(context, 1234))
}
Run Code Online (Sandbox Code Playgroud)

getExtras()这工作正常,但是在生产中,标记的行有时会导致应用程序在调用时崩溃。根据文档,它可以为空,但它不应该引发异常。

崩溃日志并不总是相同,但这种情况发生在BaseBundle

java.lang.NullPointerException
Attempt to invoke virtual method 'int android.os.Parcel.dataSize()' on a null object reference

BaseBundle.java line 164 in android.os.BaseBundle.<init>()
Bundle.java line 106 in android.os.Bundle.<init>()
Intent.java line 6580 in android.content.Intent.getExtras()
Run Code Online (Sandbox Code Playgroud)

...或者发生这种情况:

java.lang.IllegalArgumentException
Duplicate key in ArrayMap:

BaseBundle.java line 126 in android.os.BaseBundle.<init>()
Bundle.java line 102 in android.os.Bundle.<init>()
Intent.java line 5756 in android.content.Intent.getExtras()
Run Code Online (Sandbox Code Playgroud)

该崩溃仅发生在 Android 5、6 或 7 上。我还没有找到在我自己的设备上重现它的方法。

我是否做错了什么,或者避免这种崩溃的最佳方法是什么?如果没有额外的捆绑包,我将无法显示我的活动。

Sau*_*rat 3

这是 AOSP 中的一个错误,在 Android 7 之后修复。以下是提交消息中的原因:

修复 writeToParcel 和 unparcel 中的竞争问题

当打包的数据可能被另一个线程回收时,不要访问它。

还要创建 mMap 的本地引用,该引用可以由另一个线程修改。