返回
Android APT系列 - 十分钟让你的AS动态生成代码
Android
2024-01-26 01:09:19
前言
前天看了公司的路由框架源码后,打算自己手撸一套路由框架,决定不用反射,而用Apt来做,因为大名鼎鼎的ButterKnife/Dragger都是用Apt来实现,到底要看看有哪些好玩的地方。在这一篇文章中,我们使用APT来实现按钮的点击控制,也算是路由框架的一个铺垫。
正文
1. 准备工作
首先,你需要确保你的Android Studio已经安装了Apt插件。如果还没有,可以按照以下步骤进行安装:
- 打开Android Studio。
- 点击“文件”菜单,然后选择“设置”。
- 在“设置”对话框中,点击“插件”选项卡。
- 在“插件”选项卡中,搜索“Apt”,然后点击“安装”按钮。
- 等待Apt插件安装完成。
2. 创建注解处理器
现在,你可以开始创建自己的注解处理器了。为此,你需要创建一个新的Android项目。在项目中,创建一个名为“AptProcessor”的新包。在“AptProcessor”包中,创建一个名为“ButtonProcessor”的新类。这个类将作为你的注解处理器。
package com.example.aptprocessor;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import java.io.IOException;
import java.util.Set;
@AutoService(Processor.class)
public class ButtonProcessor extends AbstractProcessor {
@Override
public Set<String> getSupportedAnnotationTypes() {
return Set.of(Button.class.getCanonicalName());
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element element : roundEnv.getElementsAnnotatedWith(Button.class)) {
TypeElement typeElement = (TypeElement) element.getEnclosingElement();
String className = typeElement.getSimpleName().toString();
String packageName = processingEnv.getElementUtils().getPackageOf(typeElement).toString();
MethodSpec onClickMethod = MethodSpec.methodBuilder("onClick")
.addModifiers(Modifier.PUBLIC)
.returns(void.class)
.addParameter(android.view.View.class, "view")
.addStatement("android.util.Log.d(\"ButtonProcessor\", \"Button clicked!\");")
.build();
TypeSpec typeSpec = TypeSpec.classBuilder(className + "$OnClickListener")
.addModifiers(Modifier.PUBLIC)
.addMethod(onClickMethod)
.build();
JavaFile javaFile = JavaFile.builder(packageName, typeSpec).build();
try {
javaFile.writeTo(processingEnv.getFiler());
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
}
3. 创建注解
接下来,你需要创建一个注解来标注那些你想动态生成的代码。为此,你需要在“AptProcessor”包中创建一个名为“Button”的新类。这个类将作为你的注解。
package com.example.aptprocessor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Button {
}
4. 使用注解
现在,你可以使用注解来标注那些你想动态生成的代码了。为此,你需要在你的代码中添加以下代码:
@Button
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new MainActivity$OnClickListener() {
@Override
public void onClick(View view) {
// Do something when the button is clicked.
}
});
}
}
5. 编译代码
现在,你可以编译你的代码了。为此,你需要点击“构建”菜单,然后选择“构建项目”。
6. 运行代码
现在,你可以运行你的代码了。为此,你需要点击“运行”按钮。
7. 查看结果
现在,你可以查看结果了。为此,你需要在日志窗口中查找以下消息:
D/ButtonProcessor: Button clicked!
结语
恭喜你!你已经成功地使用Android APT动态生成了代码。现在,你可以开始学习更高级的APT技巧,比如如何使用APT来实现路由框架。