天天看點

Android自定義apt

在看dagger的源碼的時候,很好奇這些源碼到底是如何生成的(傳送門)

搜了下資料,弄清楚了。網上相關資料不多,自己做下記錄,防止忘了。

流程圖如下:

Android自定義apt

1. 建立注解lib:

  1. 建立Java library(不是Android Library)
  2. 建立Inject注解類
    Android自定義apt
@Target(ElementType.TYPE)
@Retention(RUNTIME)
@Documented
public @interface Inject {
}
           

2. 建立apt lib

  1. 引入三房庫
  2. 引入注解lib
  3. 生成代碼邏輯
    Android自定義apt
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.auto.service:auto-service:1.0-rc2'
    implementation 'com.squareup:javapoet:1.7.0'
    implementation project(':my_an_lib')
}
           
@AutoService(Processor.class)
public class Inject_Apt extends AbstractProcessor {
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return Collections.singleton(Inject.class.getCanonicalName());
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        MethodSpec get = MethodSpec.methodBuilder("get")
                .addModifiers(Modifier.PUBLIC,Modifier.STATIC)
                .returns(String.class)
                .addStatement("return"+"\"Hello World!\"")
                .build();
        TypeSpec helloWorld = TypeSpec.classBuilder("YsTest")
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .addMethod(get)
                .build();
        JavaFile javaFile = JavaFile.builder("yang.shuai", helloWorld)
                .build();
        try {
            javaFile.writeTo(processingEnv.getFiler());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

           

3. App lib引入注解lib和apt lib

implementation project(':my_an_lib')
annotationProcessor project(':my_apt_lib')
           

4. MainActivity添加注解

@Inject
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
           

5. build->rebuild project 生成檔案YsTest

Android自定義apt
public final class YsTest {
  public static String get() {
    return"Hello World!";
  }
}
           

6. MainActivity 中添加調用

@Inject
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.w("測試", YsTest.get());
    }
}
           

運作結果:

繼續閱讀