16

Starting from API level 33 the getSerializable(String) method of Bundle class is deprecated. Documentation suggests to use getSerializable(String, Class) instead. But that function is only available from API level 33.

My current code:

val model = args.getSerializable("key") as? Model

Is this how it should be now?

val model = args.customGetSerializable<Model>("key")

@Suppress("DEPRECATION")
inline fun <reified T : Serializable> Bundle.customGetSerializable(key: String): T? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        getSerializable(key, T::class.java)
    } else {
        getSerializable(key) as? T
    }
}
Marat
  • 6,142
  • 6
  • 39
  • 67
  • A good point. Maybe also use `Parcelable`? – CoolMind Aug 17 '22 at 11:58
  • Good suggestion. I'm actually using Parcelable for more other models. In this case the piece of code above was actually used for Enum, so "Model" in example is an enum. What do you think about it? Should I stick to the code above or maybe replace it with this https://stackoverflow.com/a/13385129/6272369 ? – Marat Aug 17 '22 at 12:08
  • `Parcelable` can be used where `Serializable` is used. Even for `Enum`. – CoolMind Aug 18 '22 at 05:48
  • @CoolMind Better advice would be: avoid passing objects big enough to make distinction between `Serializable` and `Parcelable` meaningful. – Agent_L Feb 27 '23 at 16:27
  • @Agent_L, agree with you. – CoolMind Feb 27 '23 at 21:26

3 Answers3

5

Is this how it should be now?

Yes.

Ideally, Google would add stuff to BundleCompat for these changes, and perhaps they will now that Android 13 is starting to ship to users.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 5
    There's already a [feature request for `BundleCompat`](https://issuetracker.google.com/issues/242048899), but the comment there pointing to [this issue](https://issuetracker.google.com/issues/240585930) that indicates that new API can crash with a `NullPointerException` means that using the new API might not actually be safe until Android U... – ianhanniballake Aug 17 '22 at 13:38
1

A lot of examples and solutions is offered for Kotlin, but it seems as if java is not getting any mileage. Herewith a java solution that works:-

List<ClassName> variable;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    //noinspection unchecked
    Class<? extends ArrayList<ClassName>> type = (Class<? extends ArrayList<ClassName>>) new ArrayList<>().getClass();
    variable = bundle.getSerializable("reference", type);
} else {
    //noinspection unchecked,deprecation
    variable = (List<ClassName>) bundle.getSerializable("reference");
}
Gustav
  • 139
  • 1
  • 5
0

What you can do is the set your Enum as Parcelable. It could be done easily with @Parcelize.

And after that, you can replace your deprecated getSerializable() by BundleCompat.getParcelable().

But you need to take care when you call putExtra() because your Enum now implement Serializable and Parcelable, so, you need to force your Enum as Parceable like this putExtra(enum as Parcelable)

Aurélien Guillard
  • 1,203
  • 8
  • 20