diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index aa29636398e49..914bd5684b4ab 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -555,6 +555,26 @@ public abstract class LayoutInflater { } } + private static final ClassLoader BOOT_CLASS_LOADER = LayoutInflater.class.getClassLoader(); + + private final boolean verifyClassLoader(Constructor constructor) { + final ClassLoader constructorLoader = constructor.getDeclaringClass().getClassLoader(); + if (constructorLoader == BOOT_CLASS_LOADER) { + // fast path for boot class loader (most common case?) - always ok + return true; + } + // in all normal cases (no dynamic code loading), we will exit the following loop on the + // first iteration (i.e. when the declaring classloader is the contexts class loader). + ClassLoader cl = mContext.getClassLoader(); + do { + if (constructorLoader == cl) { + return true; + } + cl = cl.getParent(); + } while (cl != null); + return false; + } + /** * Low-level function for instantiating a view by name. This attempts to * instantiate a view class of the given name found in this @@ -575,6 +595,10 @@ public abstract class LayoutInflater { public final View createView(String name, String prefix, AttributeSet attrs) throws ClassNotFoundException, InflateException { Constructor constructor = sConstructorMap.get(name); + if (constructor != null && !verifyClassLoader(constructor)) { + constructor = null; + sConstructorMap.remove(name); + } Class clazz = null; try {