Merge "Adding typed Parcel read APIs for Serializable."
This commit is contained in:
@@ -31473,6 +31473,7 @@ package android.os {
|
||||
method @Nullable public android.os.PersistableBundle readPersistableBundle();
|
||||
method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
|
||||
method @Nullable public java.io.Serializable readSerializable();
|
||||
method @Nullable public <T extends java.io.Serializable> T readSerializable(@Nullable ClassLoader, @NonNull Class<T>);
|
||||
method @NonNull public android.util.Size readSize();
|
||||
method @NonNull public android.util.SizeF readSizeF();
|
||||
method @Nullable public <T> android.util.SparseArray<T> readSparseArray(@Nullable ClassLoader);
|
||||
|
||||
@@ -2448,9 +2448,9 @@ public final class Parcel {
|
||||
|
||||
writeByteArray(baos.toByteArray());
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException("Parcelable encountered " +
|
||||
"IOException writing serializable object (name = " + name +
|
||||
")", ioe);
|
||||
throw new BadParcelableException("Parcelable encountered "
|
||||
+ "IOException writing serializable object (name = "
|
||||
+ name + ")", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3818,7 +3818,7 @@ public final class Parcel {
|
||||
break;
|
||||
|
||||
case VAL_SERIALIZABLE:
|
||||
object = readSerializable(loader);
|
||||
object = readSerializableInternal(loader, clazz);
|
||||
break;
|
||||
|
||||
case VAL_PARCELABLEARRAY:
|
||||
@@ -4144,12 +4144,37 @@ public final class Parcel {
|
||||
* wasn't found in the parcel.
|
||||
*/
|
||||
@Nullable
|
||||
public final Serializable readSerializable() {
|
||||
return readSerializable(null);
|
||||
public Serializable readSerializable() {
|
||||
return readSerializableInternal(/* loader */ null, /* clazz */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #readSerializable()} but accepts {@code loader} parameter
|
||||
* as the primary classLoader for resolving the Serializable class; and {@code clazz} parameter
|
||||
* as the required type.
|
||||
*
|
||||
* @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
|
||||
* is not an instance of that class or any of its children class or there there was an error
|
||||
* deserializing the object.
|
||||
*/
|
||||
@Nullable
|
||||
private final Serializable readSerializable(@Nullable final ClassLoader loader) {
|
||||
public <T extends Serializable> T readSerializable(@Nullable ClassLoader loader,
|
||||
@NonNull Class<T> clazz) {
|
||||
Objects.requireNonNull(clazz);
|
||||
return readSerializableInternal(loader, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz The type of the serializable expected or {@code null} for performing no checks
|
||||
*/
|
||||
@Nullable
|
||||
private <T> T readSerializableInternal(@Nullable final ClassLoader loader,
|
||||
@Nullable Class<T> clazz) {
|
||||
if (clazz != null && !Serializable.class.isAssignableFrom(clazz)) {
|
||||
throw new BadParcelableException("About to unparcel a serializable object "
|
||||
+ " but class required " + clazz.getName() + " is not Serializable");
|
||||
}
|
||||
|
||||
String name = readString();
|
||||
if (name == null) {
|
||||
// For some reason we were unable to read the name of the Serializable (either there
|
||||
@@ -4158,9 +4183,20 @@ public final class Parcel {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] serializedData = createByteArray();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
|
||||
try {
|
||||
if (clazz != null && loader != null) {
|
||||
// If custom classloader is provided, resolve the type of serializable using the
|
||||
// name, then check the type before deserialization. As in this case we can resolve
|
||||
// the class the same way as ObjectInputStream, using the provided classloader.
|
||||
Class<?> cl = Class.forName(name, false, loader);
|
||||
if (!clazz.isAssignableFrom(cl)) {
|
||||
throw new BadParcelableException("Serializable object "
|
||||
+ cl.getName() + " is not a subclass of required class "
|
||||
+ clazz.getName() + " provided in the parameter");
|
||||
}
|
||||
}
|
||||
byte[] serializedData = createByteArray();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
|
||||
ObjectInputStream ois = new ObjectInputStream(bais) {
|
||||
@Override
|
||||
protected Class<?> resolveClass(ObjectStreamClass osClass)
|
||||
@@ -4168,22 +4204,31 @@ public final class Parcel {
|
||||
// try the custom classloader if provided
|
||||
if (loader != null) {
|
||||
Class<?> c = Class.forName(osClass.getName(), false, loader);
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
return Objects.requireNonNull(c);
|
||||
}
|
||||
return super.resolveClass(osClass);
|
||||
}
|
||||
};
|
||||
return (Serializable) ois.readObject();
|
||||
T object = (T) ois.readObject();
|
||||
if (clazz != null && loader == null) {
|
||||
// If custom classloader is not provided, check the type of the serializable using
|
||||
// the deserialized object, as we cannot resolve the class the same way as
|
||||
// ObjectInputStream.
|
||||
if (!clazz.isAssignableFrom(object.getClass())) {
|
||||
throw new BadParcelableException("Serializable object "
|
||||
+ object.getClass().getName() + " is not a subclass of required class "
|
||||
+ clazz.getName() + " provided in the parameter");
|
||||
}
|
||||
}
|
||||
return object;
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException("Parcelable encountered " +
|
||||
"IOException reading a Serializable object (name = " + name +
|
||||
")", ioe);
|
||||
throw new BadParcelableException("Parcelable encountered "
|
||||
+ "IOException reading a Serializable object (name = "
|
||||
+ name + ")", ioe);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new RuntimeException("Parcelable encountered " +
|
||||
"ClassNotFoundException reading a Serializable object (name = "
|
||||
+ name + ")", cnfe);
|
||||
throw new BadParcelableException("Parcelable encountered "
|
||||
+ "ClassNotFoundException reading a Serializable object (name = "
|
||||
+ name + ")", cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user