为什么当 getParcelable 在不同的地方时不同的 parceable 被实例化

问题描述

在android中有一些可分割的类

@Parcelize
class ParcelableClassA(private val member: Int) : IAParcelable {
    init {
        Log.e("+++","+++ ParcelableClassA::init{},this: $this")
    }

@Parcelize
class ParcelableClassB(private val member: String) : IBParcelable {
    init {
        Log.e("+++","+++ ParcelableClassB::init{},this: $this")
    }

在某些地方,它被实例化并放在一个包中以创建活动。

Intent(context,TheActivity::class.java).apply {
    val bundle = Bundle()
    bundle.putParcelable(EXTRAS_CLASS_A,ParcelableClassA(1))
    bundle.putParcelable(EXTRAS_CLASS_B,ParcelableClassB("B")
...
    putExtras(bundle)

    context.startActivity(this)
}

在活动类中:

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

        val classA = intent.extras?.getParcelable(EXTRAS_CLASS_A) as? IAParcelable
        val classB = intent.extras?.getParcelable(EXTRAS_CLASS_B) as? IBParcelable

}

预计只有一个打印输出"+++ ParcelableClassA::init{},this: $this" 但实际上看到 ParcelableClassA 的两个实例被创建,一个

intent.extras?.getParcelable(EXTRAS_CLASS_A)

而另一个也发生在

intent.extras?.getParcelable(EXTRAS_CLASS_B)

调用。所以 ParcelableClassA::init{} 和 ParcelableClassB::init{} 都被调用了两次。

如果有更多的数据放入额外的,ParcelableClassA的实例化被调用的越多,这只是浪费。

这是预期的行为还是此处的执行方式不正确?

更新: 似乎在 BaseBundle 中,如果在 unparcel() 中并且 mParcelledData 不为空,它将具有此行为。但不确定为什么会发生。 如果一步一步调试好像mParcelledData一直是null,不会出现这个问题,但是直接运行就会出现这个问题。

void unparcel() {
        synchronized (this) {
            final Parcel source = mParcelledData;
            if (source != null) {
                initializefromParcelLocked(source,/*recycleParcel=*/ true,mParcelledByNative);
            } else {
                if (DEBUG) {
                    Log.d(TAG,"unparcel "
                            + Integer.toHexString(System.identityHashCode(this))
                            + ": no parcelled data");
                }
            }
        }
    }

解决方法

貌似使用了intent.extra?导致问题。

如果改为

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

        var bundle  = intent.extras

        val classA = bundle?.getParcelable(EXTRAS_CLASS_A) as? IAParcelable
        val classB = bundle?.getParcelable(EXTRAS_CLASS_B) as? IBParcelable

}

似乎没有看到重复。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...