Skip to content

lofiwang/javapoet-android

Repository files navigation

javapoet-android 基于square JavaPoet

JavaPoet GitHub
JavaPoet 中文翻译

JavaPoet生成Android常用代码

  1. 生成JavaBean
  2. 生成Parcelable
  3. 生成Builder
  4. 生成PcsBean(PropertyChangeSupport)
原始代码
@PoetCode
public class Person {
    private String name;
}
  1. construct()
    public static MethodSpec createConstructMethod(Modifier... modifiers) {
        MethodSpec.Builder method = MethodSpec.constructorBuilder()
                .addModifiers(modifiers);
        return method.build();
    }
    --------------------------------------------------------------------------------
    public PersonBean() {
    }
  1. get()
    public static MethodSpec createGet(String fieldName, TypeName fieldType, Modifier... modifiers) {
        String methodName = "get" + upperFirstChar(fieldName);
        MethodSpec.Builder method = MethodSpec.methodBuilder(methodName)
                .addModifiers(modifiers)
                .returns(fieldType)
                .addStatement("return " + fieldName);
        return method.build();
    }
    --------------------------------------------------------------------------------
    public String getName() {
        return name;
    }
  1. set()
    public static MethodSpec createSet(String fieldName, TypeName fieldType, Modifier... modifiers) {
        String methodName = "set" + upperFirstChar(fieldName);
        MethodSpec.Builder method = MethodSpec.methodBuilder(methodName)
                .addModifiers(modifiers)
                .addParameter(fieldType, fieldName)
                .addStatement("this." + fieldName + "=" + fieldName);
        return method.build();
    }
    --------------------------------------------------------------------------------
    public void setName(String name) {
        this.name = name;
    }
  1. toString()
    public static MethodSpec createToString(String clazzName, HashMap<String, TypeName> fieldMap, Modifier... modifiers) {
        String methodName = "toString";
        MethodSpec.Builder method = MethodSpec.methodBuilder(methodName)
                .addModifiers(modifiers)
                .addAnnotation(Override.class)
                .returns(String.class);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("\"")
                .append(clazzName)
                .append("{\"");
        for (String field : fieldMap.keySet()) {
            stringBuilder.append(" + \"").append(field).append(":\" + ").append(field);
        }
        stringBuilder.append(" + \"}\"");
        method.addStatement("return " + stringBuilder.toString());
        return method.build();
    }
    --------------------------------------------------------------------------------
    @Override
    public String toString() {
        return "PersonBean{" + "name:" + name + "}";
    }
  1. implements Parcelable
ClassName parcelableType = ClassName.get("android.os", "Parcelable");
ClassName parcelType = ClassName.get("android.os", "Parcel");
ClassName parcelableCreator = ClassName.get("android.os", "Parcelable", "Creator");
TypeName creatorFieldType = ParameterizedTypeName.get(parcelableCreator, typeName);
typeSpecBuilder.addSuperinterface(parcelableType);
--------------------------------------------------------------------------------
public class PersonParcelable implements Parcelable {}
  1. construct()
    public static MethodSpec createConstructMethod(Modifier... modifiers) {
        MethodSpec.Builder method = MethodSpec.constructorBuilder()
                .addModifiers(modifiers);
    }
    --------------------------------------------------------------------------------
    public PersonParcelable() {
    }
  1. construct(Parcel)
            MethodSpec.Builder method2 = MethodSpec.constructorBuilder()
                    .addModifiers(Modifier.PUBLIC)
                    .addParameter(parcelType, "in")
                    .addStatement("$T classLoader = this.getClass().getClassLoader()", ClassLoader.class);
            for (String field : fieldMap.keySet()) {
                method2.addStatement("this.$L = ($T)in.readValue(classLoader)", field, fieldMap.get(field));
            }
            --------------------------------------------------------------------------------
    public PersonParcelable(Parcel in) {
        ClassLoader classLoader = this.getClass().getClassLoader();
        this.name = (String) in.readValue(classLoader);
    }
  1. describeContents()
            MethodSpec.Builder method = MethodSpec.methodBuilder("describeContents")
                    .addModifiers(Modifier.PUBLIC)
                    .addAnnotation(Override.class)
                    .returns(int.class)
                    .addStatement("return 0");
            --------------------------------------------------------------------------------
    @Override
    public int describeContents() {
        return 0;
    } 
  1. writeToParcel(Parcel dest, int flags)
            MethodSpec.Builder method1 = MethodSpec.methodBuilder("writeToParcel")
                    .addModifiers(Modifier.PUBLIC)
                    .addAnnotation(Override.class)
                    .addParameter(parcelType, "dest")
                    .addParameter(int.class, "flags");
            for (String field : fieldMap.keySet()) {
                method1.addStatement("dest.writeValue($L)", "this." + field);
            }
            --------------------------------------------------------------------------------
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(this.name);
    }
  1. CREATOR
            ArrayTypeName newTypeArray = ArrayTypeName.of(typeName);
            TypeSpec parcelableCreatorType = TypeSpec.anonymousClassBuilder("")
                    .addSuperinterface(creatorFieldType)
                    .addMethod(MethodSpec.methodBuilder("createFromParcel")
                            .addAnnotation(Override.class)
                            .addModifiers(Modifier.PUBLIC)
                            .addParameter(parcelType, "source")
                            .returns(typeName)
                            .addStatement("return new $T($N)", typeName, "source")
                            .build())
                    .addMethod(MethodSpec.methodBuilder("newArray")
                            .addAnnotation(Override.class)
                            .addModifiers(Modifier.PUBLIC)
                            .addParameter(int.class, "size")
                            .returns(newTypeArray)
                            .addStatement("return new $T[$N]", typeName, "size")
                            .build())
                    .build();
            FieldSpec.Builder creatorField = FieldSpec.builder(creatorFieldType, "CREATOR")
                    .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
                    .initializer("$L", parcelableCreatorType);
            --------------------------------------------------------------------------------
    public static final Parcelable.Creator<PersonParcelable> CREATOR = new Parcelable.Creator<PersonParcelable>() {
        @Override
        public PersonParcelable createFromParcel(Parcel source) {
            return new PersonParcelable(source);
        }

        @Override
        public PersonParcelable[] newArray(int size) {
            return new PersonParcelable[size];
        }
    };
  1. Builder
        public static void createBuilder(String pkgName, String newClazzName, TypeSpec.Builder typeSpecBuilder, HashMap<String, TypeName> fieldMap) {
            ClassName newClassName = PoetCodeUtil.createNewClazzType(pkgName, newClazzName);
            ClassName builderClassName = PoetCodeUtil.createNewClazzType(pkgName, newClazzName, "Builder");
            TypeSpec.Builder typeSpecB = TypeSpec.classBuilder("Builder")
                    .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
            for (String field : fieldMap.keySet()) {
                typeSpecB.addField(fieldMap.get(field), field, Modifier.PRIVATE)
                        .addMethod(PoetCodeUtil.createSetReturn(builderClassName, field, fieldMap.get(field), Modifier.PUBLIC));
            }
            MethodSpec.Builder methodSpecB = MethodSpec.methodBuilder("create")
                    .addModifiers(Modifier.PUBLIC)
                    .returns(newClassName)
                    .addStatement("$T outClazz = new $T()", newClassName, newClassName);
            for (String field : fieldMap.keySet()) {
                methodSpecB.addStatement("outClazz.$L = $L", field, field);
            }
            methodSpecB.addStatement("return outClazz");
            typeSpecB.addMethod(methodSpecB.build());
            typeSpecBuilder.addType(typeSpecB.build());
        }
        --------------------------------------------------------------------------------
  public static class Builder {
    private String name;

    private int age;

    public Builder setName(String name) {
      this.name = name;
      return this;
    }

    public Builder setAge(int age) {
      this.age = age;
      return this;
    }

    public PersonBuilderPattern create() {
      PersonBuilderPattern outClazz = new PersonBuilderPattern();
      outClazz.name = name;
      outClazz.age = age;
      return outClazz;
    }
  }
  1. field
        public static FieldSpec createPcsField() {
            FieldSpec.Builder pcsField = FieldSpec.builder(PropertyChangeSupport.class, "pcs")
                    .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
                    .initializer("new $T(this)", PropertyChangeSupport.class);
            return pcsField.build();
        }
        --------------------------------------------------------------------------------
  private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
  1. get()
    public static MethodSpec createGet(String fieldName, TypeName fieldType, Modifier... modifiers) {
        String methodName = "get" + upperFirstChar(fieldName);
        MethodSpec.Builder method = MethodSpec.methodBuilder(methodName)
                .addModifiers(modifiers)
                .returns(fieldType)
                .addStatement("return " + fieldName);
        return method.build();
    }
    --------------------------------------------------------------------------------
    public String getName() {
        return name;
    }
  1. set()
        public static MethodSpec createPcsSet(String fieldName, TypeName fieldType, Modifier... modifiers) {
            String methodName = "set" + upperFirstChar(fieldName);
            MethodSpec.Builder method = MethodSpec.methodBuilder(methodName)
                    .addModifiers(modifiers)
                    .addParameter(fieldType, fieldName)
                    .addStatement("$T old$L = this.$L",fieldType,fieldName,fieldName)
                    .addStatement("this.$L = $L", fieldName, fieldName)
                    .addStatement("this.pcs.firePropertyChange($S,old$L,$L)",fieldName,fieldName,fieldName);
            return method.build();
        }
        --------------------------------------------------------------------------------
  public void setName(String name) {
    String oldname = this.name;
    this.name = name;
    this.pcs.firePropertyChange("name",oldname,name);
  }
  1. add listener
        public static MethodSpec createAddListenerMethod() {
            MethodSpec.Builder pcsMethod = MethodSpec.methodBuilder("addPropertyChangeListener")
                    .addModifiers(Modifier.PUBLIC)
                    .addParameter(PropertyChangeListener.class,"listener")
                    .addStatement("this.pcs.addPropertyChangeListener(listener)");
            return pcsMethod.build();
        }
        --------------------------------------------------------------------------------
  public void addPropertyChangeListener(PropertyChangeListener listener) {
    this.pcs.addPropertyChangeListener(listener);
  }
  1. remove listener
        public static MethodSpec createRemoveListenerMethod() {
            MethodSpec.Builder pcsMethod = MethodSpec.methodBuilder("removePropertyChangeListener")
                    .addModifiers(Modifier.PUBLIC)
                    .addParameter(PropertyChangeListener.class,"listener")
                    .addStatement("this.pcs.removePropertyChangeListener(listener)");
            return pcsMethod.build();
        }
        --------------------------------------------------------------------------------
  public void removePropertyChangeListener(PropertyChangeListener listener) {
    this.pcs.removePropertyChangeListener(listener);
  }