标签:exception csdn 统一 apple abstract 映射关系 导包 ide load
/**
* <pre>
* @author 杨充
* blog : https://github.com/yangchong211
* time : 2017/06/21
* desc : 一定time时间内该点击事件只能执行一次
* revise:
* </pre>
*/
//@Retention用来修饰这是一个什么类型的注解。这里表示该注解是一个编译时注解。
@Retention(RetentionPolicy.CLASS)
//@Target用来表示这个注解可以使用在哪些地方。
// 比如:类、方法、属性、接口等等。这里ElementType.METHOD 表示这个注解可以用来修饰:方法
@Target(ElementType.METHOD)
//这里的interface并不是说OnceClick是一个接口。就像申明类用关键字class。申明注解用的就是@interface。
public @interface OnceClick {
//返回值表示这个注解里可以存放什么类型值
int value();
}
/**
* <pre>
* @author 杨充
* blog : https://github.com/yangchong211
* time : 2017/06/21
* desc : 自定义Processor编译器
* revise:
* </pre>
*/
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class OnceClickProcessor extends AbstractProcessor {
private Messager messager;
private Elements elementUtils;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
messager = processingEnv.getMessager();
elementUtils = processingEnv.getElementUtils();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
//获取proxyMap
Map<String, OnceProxyInfo> proxyMap = getProxyMap(roundEnv);
//遍历proxyMap,并生成代码
for (String key : proxyMap.keySet()) {
OnceProxyInfo proxyInfo = proxyMap.get(key);
writeCode(proxyInfo);
}
return true;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new LinkedHashSet<>();
types.add(OnceClick.class.getCanonicalName());
return types;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return super.getSupportedSourceVersion();
}
}
apply plugin: ‘java-library‘
dependencies {
implementation fileTree(dir: ‘libs‘, include: [‘*.jar‘])
implementation ‘com.google.auto.service:auto-service:1.0-rc3‘
implementation ‘com.squareup:javapoet:1.10.0‘
implementation project(‘:OnceClickAnnotation‘)
}
sourceCompatibility = "7"
targetCompatibility = "7"
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化OnceClick,并设置点击事件间隔是2秒
OnceInit.once(this,2000);
}
@OnceClick(R.id.tv_1)
public void Click1(){
Log.d("tag--------------------","tv_1");
}
@OnceClick(R.id.tv_2)
public void Click2(View v){
Log.d("tag--------------------","tv_2");
}
}
// 编译生成的代码,不要修改
// 更多内容:https://github.com/yangchong211
package com.ycbjie.ycapt;
import android.view.View;
import com.ycbjie.api.Finder;
import com.ycbjie.api.AbstractInjector;
public class MainActivity$$_Once_Proxy<T extends MainActivity> implements AbstractInjector<T> {
public long intervalTime;
@Override
public void setIntervalTime(long time) {
intervalTime = time;
}
@Override
public void inject(final Finder finder, final T target, Object source) {
View view;
view = finder.findViewById(source, 2131165325);
if(view != null){
view.setOnClickListener(new View.OnClickListener() {
long time = 0L;
@Override
public void onClick(View v) {
long temp = System.currentTimeMillis();
if (temp - time >= intervalTime) {
time = temp;
target.Click1();
}
}});
}
view = finder.findViewById(source, 2131165326);
if(view != null){
view.setOnClickListener(new View.OnClickListener() {
long time = 0L;
@Override
public void onClick(View v) {
long temp = System.currentTimeMillis();
if (temp - time >= intervalTime) {
time = temp;
target.Click2(v);
}
}});
}
}
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
//获取proxyMap
Map<String, OnceProxyInfo> proxyMap = getProxyMap(roundEnv);
//遍历proxyMap,并生成代码
for (String key : proxyMap.keySet()) {
OnceProxyInfo proxyInfo = proxyMap.get(key);
//写入代码
writeCode(proxyInfo);
}
return true;
}
public class OnceProxyInfo {
private String packageName;
private String targetClassName;
private String proxyClassName;
private TypeElement typeElement;
private List<OnceMethod> methods;
private static final String PROXY = "_Once_Proxy";
OnceProxyInfo(String packageName, String className) {
this.packageName = packageName;
this.targetClassName = className;
this.proxyClassName = className + "$$" + PROXY;
}
String getProxyClassFullName() {
return packageName + "." + proxyClassName;
}
String generateJavaCode() throws OnceClickException {
StringBuilder builder = new StringBuilder();
builder.append("// 编译生成的代码,不要修改\n");
builder.append("// 更多内容:https://github.com/yangchong211\n");
builder.append("package ").append(packageName).append(";\n\n");
//写入导包
builder.append("import android.view.View;\n");
builder.append("import com.ycbjie.api.Finder;\n");
builder.append("import com.ycbjie.api.AbstractInjector;\n");
builder.append(‘\n‘);
builder.append("public class ").append(proxyClassName)
.append("<T extends ").append(getTargetClassName()).append(">")
.append(" implements AbstractInjector<T>").append(" {\n");
builder.append(‘\n‘);
generateInjectMethod(builder);
builder.append(‘\n‘);
builder.append("}\n");
return builder.toString();
}
private String getTargetClassName() {
return targetClassName.replace("$", ".");
}
private void generateInjectMethod(StringBuilder builder) throws OnceClickException {
builder.append(" public long intervalTime; \n");
builder.append(‘\n‘);
builder.append(" @Override \n")
.append(" public void setIntervalTime(long time) {\n")
.append(" intervalTime = time;\n } \n");
builder.append(‘\n‘);
builder.append(" @Override \n")
.append(" public void inject(final Finder finder, final T target, Object source) {\n");
builder.append(" View view;");
builder.append(‘\n‘);
//这一步是遍历所有的方法
for (OnceMethod method : getMethods()) {
builder.append(" view = ")
.append("finder.findViewById(source, ")
.append(method.getId())
.append(");\n");
builder.append(" if(view != null){\n")
.append(" view.setOnClickListener(new View.OnClickListener() {\n")
.append(" long time = 0L;\n");
builder.append(" @Override\n")
.append(" public void onClick(View v) {\n");
builder.append(" long temp = System.currentTimeMillis();\n")
.append(" if (temp - time >= intervalTime) {\n" +
" time = temp;\n");
if (method.getMethodParametersSize() == 1) {
if (method.getMethodParameters().get(0).equals("android.view.View")) {
builder.append(" target.")
.append(method.getMethodName()).append("(v);");
} else {
throw new OnceClickException("Parameters must be android.view.View");
}
} else if (method.getMethodParametersSize() == 0) {
builder.append(" target.")
.append(method.getMethodName()).append("();");
} else {
throw new OnceClickException("Does not support more than one parameter");
}
builder.append("\n }\n")
.append(" }")
.append("});\n }\n");
}
builder.append(" }\n");
}
TypeElement getTypeElement() {
return typeElement;
}
void setTypeElement(TypeElement typeElement) {
this.typeElement = typeElement;
}
List<OnceMethod> getMethods() {
return methods == null ? new ArrayList<OnceMethod>() : methods;
}
void addMethod(OnceMethod onceMethod) {
if (methods == null) {
methods = new ArrayList<>();
}
methods.add(onceMethod);
}
}
public class OnceMethod {
private int id;
private String methodName;
private List<String> methodParameters;
OnceMethod(int id, String methodName, List<String> methodParameters) {
this.id = id;
this.methodName = methodName;
this.methodParameters = methodParameters;
}
int getMethodParametersSize() {
return methodParameters == null ? 0 : methodParameters.size();
}
int getId() {
return id;
}
String getMethodName() {
return methodName;
}
List<String> getMethodParameters() {
return methodParameters;
}
}
标签:exception csdn 统一 apple abstract 映射关系 导包 ide load
原文地址:https://www.cnblogs.com/yc211/p/10445926.html