Home > Software design >  'Bundle.GetParcelable(string?)' is obsolete: 'deprecated'
'Bundle.GetParcelable(string?)' is obsolete: 'deprecated'

Time:10-29

So I have this obsolescence issue using VS 2022 Xamarin and android api 33 (Triamisu), I don't want to use the [Obsolete] key word as although the app works fine on my Samsung S21 (Android v13) phone, eventually all support for earlier versions of android will drop off and I will have to update all my code anyway. So in the interest of getting ahead of this, I'm putting the question out there.

Currently my code is:

User MyUser = new User("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
MyUser = bundlee.GetParcelable("MyUser") as User;

I move the user data from one activity to another so I don't have to make another call to the database, hopefully saving time. I read the article here and can't really figure out what syntax I need in order to correct the code. User is a class defined in my code and I populate an instance of the class with the user's data. I move the data from one activity to another like this:

Intent intent = new Intent(this, typeof(Menu));
Bundle bundlee = new Bundle();
bundlee.PutParcelable("MyUser", MyUser); // Persist user class to next activity
intent.PutExtra("TheBundle", bundlee);
StartActivity(intent);

Now apparently things are changing and I cannot figure out how to adapt my code to the change. There isn't a lot of information out there as this is a recent change, I've read the android developer documentation here but it wasn't much help. What class clazz do I use in this instance? I created the class I'm passing in c#, so it's not java. I'm very confused. Can anyone clear this up for me?

CodePudding user response:

A quick look at the source code (available online) confirms what you are experiencing:

/* @deprecated Use the type-safer {@link #getParcelable(String, Class)} starting from Android
*      {@link Build.VERSION_CODES#TIRAMISU}.
*/
@Deprecated
@Nullable
public <T extends Parcelable> T getParcelable(@Nullable String key) {
  //Implementation here
}

As you can see, the comment is recommending you use the other (type-safer) method instead:

/**
 * Returns the value associated with the given key or {@code null} if:
 * <ul>
 *     <li>No mapping of the desired type exists for the given key.
 *     <li>A {@code null} value is explicitly associated with the key.
 *     <li>The object is not of type {@code clazz}.
 * </ul>
 *
 * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
 * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
 * Otherwise, this method might throw an exception or return {@code null}.
 *
 * @param key a String, or {@code null}
 * @param clazz The type of the object expected
 * @return a Parcelable value, or {@code null}
 */
@SuppressWarnings("unchecked")
@Nullable
public <T> T getParcelable(@Nullable String key, @NonNull Class<T> clazz) {
    // The reason for not using <T extends Parcelable> is because the caller could provide a
    // super class to restrict the children that doesn't implement Parcelable itself while the
    // children do, more details at b/210800751 (same reasoning applies here).
    return get(key, clazz);
}

The new method even has a comment as to why you want to use this instead.

Notice this in particular:

  • @param clazz The type of the object expected

So, to answer your question, it looks like you should be doing this to get the object:

User MyUser = new User("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
MyUser = bundlee.GetParcelable("MyUser", Java.Lang.Class.FromType(typeof(User))) as User;

Or:

MyUser = bundlee.GetParcelable("MyUser", Java.Lang.Class.FromType(MyUser.GetType())) as User;
  • Related