Skip to content

Instantly share code, notes, and snippets.

@pietrocaselani
Created October 17, 2013 01:11
Show Gist options
  • Save pietrocaselani/7017720 to your computer and use it in GitHub Desktop.
Save pietrocaselani/7017720 to your computer and use it in GitHub Desktop.
Generate simple class with dexmaker (https://github.com/crittercism/dexmaker)
/*
public class Person {
private String mName;
public Person() {}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
*/
public class GeneretePerson {
private static DexMaker dexMaker;
private File mOutputDir;
public GeneretePerson(File outputDir) {
mOutputDir = outputDir;
dexMaker = new DexMaker();
}
public void generate() throws Exception {
String fileName = "Person.java";
TypeId<Object> person = TypeId.get("Lcom/example/DexMaker1/Person;");
dexMaker.declare(person, fileName, Modifier.PUBLIC, TypeId.OBJECT);
FieldId<Object, String> nameField = person.getField(TypeId.STRING, "mName");
dexMaker.declare(nameField, PRIVATE, null);
addDefaultConstructor(person);
generateGetter("getName", nameField, person);
generateSetter("setName", nameField, person);
ClassLoader loader = dexMaker.generateAndLoad(GeneretePerson.class.getClassLoader(), mOutputDir);
Class<?> personClass = loader.loadClass("com.example.DexMaker1.Person");
Object o = personClass.newInstance();
Method[] declaredMethods = personClass.getDeclaredMethods();
Method getter = null, setter = null;
if (declaredMethods != null) {
for (Method method : declaredMethods) {
if (method.getName().contains("get") || method.getName().contains("is")) {
getter = method;
} else if (method.getName().contains("set")) {
setter = method;
}
}
}
if (getter != null && setter != null) {
setter.invoke(o, "New Name");
Object oReturn = getter.invoke(o);
Log.v("DexMaker", oReturn.toString());
}
}
private <T, V> void generateGetter(String methodName, FieldId<T, V> fieldId, TypeId<T> target) {
MethodId<?, V> getter = target.getMethod(fieldId.getType(), methodName);
Code code = dexMaker.declare(getter, PUBLIC);
Local<V> local = code.newLocal(fieldId.getType());
Local<T> thiz = code.getThis(target);
code.iget(fieldId, local, thiz);
code.returnValue(local);
}
private <D, V> void generateSetter(String methodName, FieldId<D, V> fieldId, TypeId<D> target) {
MethodId<D, Void> setter = target.getMethod(TypeId.VOID, methodName, fieldId.getType());
Code code = dexMaker.declare(setter, PUBLIC);
Local<D> thiz = code.getThis(target);
Local<V> value = code.getParameter(0, fieldId.getType());
code.iput(fieldId, thiz, value);
code.returnVoid();
}
private void addDefaultConstructor(TypeId<?> typeId) {
Code code = dexMaker.declare(typeId.getConstructor(), PUBLIC);
Local<?> thisRef = code.getThis(typeId);
code.invokeDirect(TypeId.OBJECT.getConstructor(), null, thisRef);
code.returnVoid();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment