1

I have a object, that has other objects inside. I need to pass that object to a FragmentDialog, so I made that object Serializable and it's working perfectly in my device.

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);
    }
}

The problem is that I'm seeing some NotSerializableException reported in google developer console, so for some reason, in some devices, is giving NotSerializableException.

It's important to say that Data object is very big, and has a lot of objects inside, with a lot of objects inside. And not all those objects are serializable, but I noticed that when you are passing the bundle to a Fragment or DialogFragment is not necessary that all the sub-objects contained in a serializable objects are serializable to pass that parent object with putSerializable in a bundle.

I know it because it's working in my device and 95% of the devices. But if I try to pass this serializable object with non serializable objects inside to an Activity with a bundle, it requires to make all the sub objects serializable too (I can't do it because then it gives outofmemory when serializing). Why is not necessary when passing it to a Fragment but it's necessary when working with Activities?

And why it's this giving me some exceptions reported in the developer console if it's working for me and for the 95% of the devices that are using this application?

halfer
  • 19,824
  • 17
  • 99
  • 186
NullPointerException
  • 36,107
  • 79
  • 222
  • 382
  • "I noticed that when you are passing the bundle to a Fragment or DialogFragment is not necessary that all the sub-objects contained in a serializable objects are serializable to pass that parent object with putSerializable in a bundle" -- yes, it is necessary. "I know it because it's working in my device and the 95% of the devices" -- not when those arguments are getting put into the saved instance state `Bundle` and being passed across process boundaries. – CommonsWare Feb 02 '20 at 20:34
  • "Why is not necessary when passing it to a Fragment but it's necessary when working with Activities?" -- because `Intent` extras *always* get passed across process boundaries. Fragment arguments may or may not (e.g., depending on whether `onSaveInstanceState()` gets called). Perhaps you should switch from arguments to some other mechanism, such as a `ViewModel`, to retain your data across configuration changes. – CommonsWare Feb 02 '20 at 20:36
  • umm, so, @CommonsWare, if I put all the classes serializable, then, the few NotSerializableException will dissapear? – NullPointerException Feb 02 '20 at 20:37
  • @CommonsWare why it's onSaveInstanceState() getting called if my app is not allowing configuration changes?. I think that you mean that this is being called when "passed across process boundaries" – NullPointerException Feb 02 '20 at 20:39
  • "if I put all the classes serializable, then, the few NotSerializableException will dissapear?" -- it would depend on whether or not that is possible. For example, a `View` is not serializable, no matter what annotation you put on it. "why it's nSaveInstanceState() getting called if my app is not allowing configuration changes?" -- the user could press the HOME button. – CommonsWare Feb 02 '20 at 20:40
  • "I think that you mean that this is being called when "passed across process boundaries" " -- the saved instance state `Bundle` is held by a core OS process, in case your process gets terminated but the user is eligible to return to the activity. See https://developer.android.com/guide/components/activities/parcelables-and-bundles, particularly the last paragraph. – CommonsWare Feb 02 '20 at 20:42

1 Answers1

1

If the Serializable really gets serialized, then you will crash with a NotSerializableException when the serialization encounters something that it cannot handle.

With an Intent extra, when you use the Intent to start an activity, start a service, or send a system broadcast, all extras will get serialized. Doing any of those things involves inter-process communication (IPC), even if the resulting activity/service/receiver happens to be in your app. So, when you pass a partially-Serializable object as an Intent extra, you will crash with a NotSerializableException quickly.

Fragment arguments are not necessarily serialized. They will be if onSaveInstanceState() is called, as arguments automatically become part of your saved instance state. It is possible that a fragment might not get called with onSaveInstanceState() very often, and so a partially-Serializable object as an argument might survive. However, inevitably, somebody will press HOME or otherwise switch to another app, and onSaveInstanceState() will get called. Then, your partially-Serializable object argument will give you a NotSerializableException.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491