diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index fe2e948bfcd91..dbe3c93738b82 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -2996,65 +2996,67 @@ public final class Parcel { return null; } Parcelable.Creator creator; + HashMap> map; synchronized (mCreators) { - HashMap> map = mCreators.get(loader); + map = mCreators.get(loader); if (map == null) { map = new HashMap<>(); mCreators.put(loader, map); } creator = map.get(name); - if (creator == null) { - try { - // If loader == null, explicitly emulate Class.forName(String) "caller - // classloader" behavior. - ClassLoader parcelableClassLoader = - (loader == null ? getClass().getClassLoader() : loader); - // Avoid initializing the Parcelable class until we know it implements - // Parcelable and has the necessary CREATOR field. http://b/1171613. - Class parcelableClass = Class.forName(name, false /* initialize */, - parcelableClassLoader); - if (!Parcelable.class.isAssignableFrom(parcelableClass)) { - throw new BadParcelableException("Parcelable protocol requires subclassing " - + "from Parcelable on class " + name); - } - Field f = parcelableClass.getField("CREATOR"); - if ((f.getModifiers() & Modifier.STATIC) == 0) { - throw new BadParcelableException("Parcelable protocol requires " - + "the CREATOR object to be static on class " + name); - } - Class creatorType = f.getType(); - if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) { - // Fail before calling Field.get(), not after, to avoid initializing - // parcelableClass unnecessarily. - throw new BadParcelableException("Parcelable protocol requires a " - + "Parcelable.Creator object called " - + "CREATOR on class " + name); - } - creator = (Parcelable.Creator) f.get(null); - } - catch (IllegalAccessException e) { - Log.e(TAG, "Illegal access when unmarshalling: " + name, e); - throw new BadParcelableException( - "IllegalAccessException when unmarshalling: " + name); - } - catch (ClassNotFoundException e) { - Log.e(TAG, "Class not found when unmarshalling: " + name, e); - throw new BadParcelableException( - "ClassNotFoundException when unmarshalling: " + name); - } - catch (NoSuchFieldException e) { - throw new BadParcelableException("Parcelable protocol requires a " - + "Parcelable.Creator object called " - + "CREATOR on class " + name); - } - if (creator == null) { - throw new BadParcelableException("Parcelable protocol requires a " - + "non-null Parcelable.Creator object called " - + "CREATOR on class " + name); - } + } + if (creator != null) { + return creator; + } - map.put(name, creator); + try { + // If loader == null, explicitly emulate Class.forName(String) "caller + // classloader" behavior. + ClassLoader parcelableClassLoader = + (loader == null ? getClass().getClassLoader() : loader); + // Avoid initializing the Parcelable class until we know it implements + // Parcelable and has the necessary CREATOR field. http://b/1171613. + Class parcelableClass = Class.forName(name, false /* initialize */, + parcelableClassLoader); + if (!Parcelable.class.isAssignableFrom(parcelableClass)) { + throw new BadParcelableException("Parcelable protocol requires subclassing " + + "from Parcelable on class " + name); } + Field f = parcelableClass.getField("CREATOR"); + if ((f.getModifiers() & Modifier.STATIC) == 0) { + throw new BadParcelableException("Parcelable protocol requires " + + "the CREATOR object to be static on class " + name); + } + Class creatorType = f.getType(); + if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) { + // Fail before calling Field.get(), not after, to avoid initializing + // parcelableClass unnecessarily. + throw new BadParcelableException("Parcelable protocol requires a " + + "Parcelable.Creator object called " + + "CREATOR on class " + name); + } + creator = (Parcelable.Creator) f.get(null); + } catch (IllegalAccessException e) { + Log.e(TAG, "Illegal access when unmarshalling: " + name, e); + throw new BadParcelableException( + "IllegalAccessException when unmarshalling: " + name); + } catch (ClassNotFoundException e) { + Log.e(TAG, "Class not found when unmarshalling: " + name, e); + throw new BadParcelableException( + "ClassNotFoundException when unmarshalling: " + name); + } catch (NoSuchFieldException e) { + throw new BadParcelableException("Parcelable protocol requires a " + + "Parcelable.Creator object called " + + "CREATOR on class " + name); + } + if (creator == null) { + throw new BadParcelableException("Parcelable protocol requires a " + + "non-null Parcelable.Creator object called " + + "CREATOR on class " + name); + } + + synchronized (mCreators) { + map.put(name, creator); } return creator;