0

I'm making an Android app which is sending 2 type of objects which implements the parcelable interface (lets call them objectA and objectB) over network as byte arrays. But on the receiving end I need to know which type of object arrived in the parcel. The parcel.readValue() method only returns Object, so on the receiving end I don't know which object should I recreate objectA or objectB. How can this be done? Do Parcels have some kind of metadata in them which describes the type of the original object?

Edit: the language is Java

Edit: Added example code

        ObjectA objA = new ObjectA("uid", "description");

        byte[] bytes = ParcelUtil.toBytes(objA); //this simulates the sending

        Object rebuilt = ParcelUtil.rebuildFromBytes(bytes); //here I don't know what am I rebuilding, objectA or objectB
        if(rebuilt instanceof Parcel){
            Parcel p = (Parcel) rebuilt;

            ObjectB oB = (ObjectB) p.readValue(ObjectB.class.getClassLoader());
            if(oB.getUid() == null){
                ObjectA oA = (ObjectA) p.readValue(ObjectA.class.getClassLoader()); //this will also be full of null values
            }
        }
DaGee
  • 92
  • 1
  • 13

1 Answers1

1

I suppose you have access to the classes that could be the possible types of the object you have received. In Java you can simply use the instanceof operator to check what the object is that you have received:

if (yourObject instanceof YourClass) {
  // Your code here
}

For Parcels there is a readValue method that accepts a class loader, call this method with your classes class loader and it should work, example:

Point pointFromParcel = (Point) parcel.readValue(Point.class.getClassLoader());

https://developer.android.com/reference/android/os/Parcel#readValue(java.lang.ClassLoader)

If you cannot know what object the wrapper class will be you could create a wrapper class with holds either a ObjectA or an ObjectB and a field to indicate which object the wrapper currently holds.

Ali Nasserzadeh
  • 1,365
  • 7
  • 15
  • Yes, but the objects I receive are byte arrays and after i unnarshall it it will be a Parcel object, so instanceof will be always false – DaGee Oct 11 '19 at 11:38
  • Then you need to supply a classloader and call .readValue on your Parcel, see https://developer.android.com/reference/android/os/Parcel#readValue(java.lang.ClassLoader) – Ali Nasserzadeh Oct 11 '19 at 14:49
  • The problem is that I don't know which object arrived to me as a parcel (objectA or objectB). And if I pass objectA's ClassLoader to the parcel.readValue, then it will create the object but it will be filled with null value if it is the wrong one and after that if I do a check if the newly created object contains null, end if it is containing null then I'n not able to read again from the parcel with ObjectB's ClassLoader. I'm adding example code to the question – DaGee Oct 12 '19 at 15:44
  • Can you try using Object.class.getClassLoader() and then checking with instanceof? Alternatively you could create a wrapper class with holds either a ObjectA or an ObjectB and a field to indicate which object the wrapper currently holds. – Ali Nasserzadeh Oct 12 '19 at 16:58
  • If I use Object.getClass.getClassLoader() then it returns an Integer class, neither objectA nor objectB (this is also the case with only getClass.getClassLoader() Edit: I have successfully solved my problem with a wrapper class that you suggested, thanks you! Could you please edit the answer to contain the solution? – DaGee Oct 12 '19 at 18:52
  • great to hear! I've added it to the answer – Ali Nasserzadeh Oct 12 '19 at 20:13