【问题标题】:DialogFragment Bundle putSerializable: Sometimes giving NotSerializableExceptionDialogFragment Bundle putSerializable:有时会给出 NotSerializableException
【发布时间】:2020-05-18 16:20:00
【问题描述】:

我有一个对象,里面有其他对象。我需要将该对象传递给 FragmentDialog,因此我使该对象可序列化,并且它在我的设备中运行良好。

public static SelectTeamDialog newInstance(Data data) {
    SelectTeamDialog dialog = new SelectTeamDialog();
    Bundle args = new Bundle();
    args.putSerializable(ARG_PARAM1, data);
    dialog.setArguments(args);
    return dialog;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        data = (Data) getArguments().getSerializable(ARG_PARAM1);
    }
}

问题是我在谷歌开发者控制台中看到了一些NotSerializableException,所以出于某种原因,在某些设备中,给出了NotSerializableException

重要的是要说Data对象很大,里面有很多对象,里面有很多对象。并非所有这些对象都是可序列化的,但我注意到,当您将包传递给 Fragment 或 DialogFragment 时,不需要序列化对象中包含的所有子对象都可以序列化,以便通过包中的 putSerializable 传递该父对象。

我知道它是因为它可以在我的设备和 95% 的设备中运行。但是,如果我尝试将这个带有不可序列化对象的可序列化对象传递给带有捆绑包的 Activity,则它也需要使所有子对象也可序列化(我不能这样做,因为它会在序列化时出现内存不足)。为什么在将其传递给 Fragment 时不需要它,但在使用活动时却是必需的?

如果它对我和使用此应用程序的 95% 的设备都有效,为什么会在开发者控制台中报告一些异常?

【问题讨论】:

  • “我注意到,当您将包传递给 Fragment 或 DialogFragment 时,不需要包含在可序列化对象中的所有子对象都可以序列化,以便通过包中的 putSerializable 传递该父对象” ——是的,这是必要的。 “我知道它是因为它在我的设备和 95% 的设备中工作”——而不是当这些参数被放入保存的实例状态 Bundle 并跨进程边界传递时。
  • "为什么在传递给 Fragment 时不需要,但在使用活动时却需要?" -- 因为Intent extras 总是 跨进程边界传递。片段参数可能会也可能不会(例如,取决于 onSaveInstanceState() 是否被调用)。也许您应该从参数切换到其他一些机制,例如 ViewModel,以便在配置更改时保留您的数据。
  • 嗯,所以,@CommonsWare,如果我把所有的类都序列化,那么,少数 NotSerializableException 会消失吗?
  • @CommonsWare 如果我的应用不允许配置更改,为什么会调用 onSaveInstanceState()?我认为您的意思是在“跨越进程边界”时调用它
  • "如果我把所有的类都序列化,那么少数 NotSerializableException 会消失吗?" ——这取决于这是否可能。例如,View 是不可序列化的,无论您在其上添加什么注释。 “如果我的应用不允许配置更改,为什么会调用 nSaveInstanceState()?” -- 用户可以按下 HOME 按钮。

标签: android android-fragments bundle serializable android-bundle


【解决方案1】:

如果Serializable 真的被序列化了,那么当序列化遇到无法处理的问题时,您将因NotSerializableException 而崩溃。

使用Intent extra,当您使用Intent 启动活动、启动服务或发送系统广播时,所有 extra 都将被序列化。做任何这些事情都涉及进程间通信(IPC),即使结果活动/服务/接收器恰好在您的应用程序中。因此,当您将部分Serializable 对象作为Intent 额外传递时,您将很快因NotSerializableException 而崩溃。

片段参数不一定是序列化的。如果调用onSaveInstanceState(),它们将是,因为参数会自动成为您保存的实例状态的一部分。一个片段可能不会经常被onSaveInstanceState() 调用,因此作为参数的部分Serializable 对象可能会继续存在。但是,不可避免地,有人会按 HOME 或以其他方式切换到另一个应用程序,onSaveInstanceState() 将被调用。然后,您的 partial-Serializable 对象参数将为您提供 NotSerializableException

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    • 2014-11-05
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多