Loading tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java +20 −8 Original line number Diff line number Diff line Loading @@ -24,9 +24,11 @@ import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; Loading Loading @@ -86,7 +88,23 @@ public class AsmGenerator { public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) { mLog = log; mOsDestJar = osDestJar; mInjectClasses = createInfo.getInjectedClasses(); ArrayList<Class<?>> injectedClasses = new ArrayList<Class<?>>(Arrays.asList(createInfo.getInjectedClasses())); // Search for and add anonymous inner classes also. ListIterator<Class<?>> iter = injectedClasses.listIterator(); while (iter.hasNext()) { Class<?> clazz = iter.next(); try { int i = 1; while(i < 100) { iter.add(Class.forName(clazz.getName() + "$" + i)); i++; } } catch (ClassNotFoundException ignored) { // Expected. } } mInjectClasses = injectedClasses.toArray(new Class<?>[0]); mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods())); // Create the map/set of methods to change to delegates Loading Loading @@ -290,13 +308,7 @@ public class AsmGenerator { * e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class" */ private String classToEntryPath(Class<?> clazz) { String name = ""; Class<?> parent; while ((parent = clazz.getEnclosingClass()) != null) { name = "$" + clazz.getSimpleName() + name; clazz = parent; } return classNameToEntryPath(clazz.getCanonicalName() + name); return classNameToEntryPath(clazz.getName()); } /** Loading tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +2 −1 Original line number Diff line number Diff line Loading @@ -136,6 +136,8 @@ public final class CreateInfo implements ICreateInfo { ICreateInfo.class, CreateInfo.class, LayoutlibDelegate.class, InjectMethodRunnable.class, InjectMethodRunnables.class, /* Java package classes */ AutoCloseable.class, Objects.class, Loading Loading @@ -302,4 +304,3 @@ public final class CreateInfo implements ICreateInfo { InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER); }}; } tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java +7 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,12 @@ public interface ICreateInfo { Map<String, InjectMethodRunnable> getInjectedMethodsMap(); abstract class InjectMethodRunnable { public abstract void generateMethods(ClassVisitor cv); /** * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when * loading the class, ClassVisitor is not loaded. This is because when injecting * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject * asm classes also, but still keep CreateInfo loadable. */ public abstract void generateMethods(Object cv); } } tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java +3 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,9 @@ public class InjectMethodRunnables { public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER = new InjectMethodRunnable() { @Override public void generateMethods(ClassVisitor cv) { public void generateMethods(Object classVisitor) { assert classVisitor instanceof ClassVisitor; ClassVisitor cv = (ClassVisitor) classVisitor; // generated by compiling the class: // class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } } // and then running ASMifier on it: Loading Loading
tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java +20 −8 Original line number Diff line number Diff line Loading @@ -24,9 +24,11 @@ import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; Loading Loading @@ -86,7 +88,23 @@ public class AsmGenerator { public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) { mLog = log; mOsDestJar = osDestJar; mInjectClasses = createInfo.getInjectedClasses(); ArrayList<Class<?>> injectedClasses = new ArrayList<Class<?>>(Arrays.asList(createInfo.getInjectedClasses())); // Search for and add anonymous inner classes also. ListIterator<Class<?>> iter = injectedClasses.listIterator(); while (iter.hasNext()) { Class<?> clazz = iter.next(); try { int i = 1; while(i < 100) { iter.add(Class.forName(clazz.getName() + "$" + i)); i++; } } catch (ClassNotFoundException ignored) { // Expected. } } mInjectClasses = injectedClasses.toArray(new Class<?>[0]); mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods())); // Create the map/set of methods to change to delegates Loading Loading @@ -290,13 +308,7 @@ public class AsmGenerator { * e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class" */ private String classToEntryPath(Class<?> clazz) { String name = ""; Class<?> parent; while ((parent = clazz.getEnclosingClass()) != null) { name = "$" + clazz.getSimpleName() + name; clazz = parent; } return classNameToEntryPath(clazz.getCanonicalName() + name); return classNameToEntryPath(clazz.getName()); } /** Loading
tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +2 −1 Original line number Diff line number Diff line Loading @@ -136,6 +136,8 @@ public final class CreateInfo implements ICreateInfo { ICreateInfo.class, CreateInfo.class, LayoutlibDelegate.class, InjectMethodRunnable.class, InjectMethodRunnables.class, /* Java package classes */ AutoCloseable.class, Objects.class, Loading Loading @@ -302,4 +304,3 @@ public final class CreateInfo implements ICreateInfo { InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER); }}; }
tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java +7 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,12 @@ public interface ICreateInfo { Map<String, InjectMethodRunnable> getInjectedMethodsMap(); abstract class InjectMethodRunnable { public abstract void generateMethods(ClassVisitor cv); /** * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when * loading the class, ClassVisitor is not loaded. This is because when injecting * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject * asm classes also, but still keep CreateInfo loadable. */ public abstract void generateMethods(Object cv); } }
tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java +3 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,9 @@ public class InjectMethodRunnables { public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER = new InjectMethodRunnable() { @Override public void generateMethods(ClassVisitor cv) { public void generateMethods(Object classVisitor) { assert classVisitor instanceof ClassVisitor; ClassVisitor cv = (ClassVisitor) classVisitor; // generated by compiling the class: // class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } } // and then running ASMifier on it: Loading