本片文章将用反射和注解仿照retrofit只需要传入一个带有给定注解的接口,通过调用接口就能直接将传入的数据和注解进行结合,生成对应参数
1,自定义注解
对字段的修饰
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface AnnotationField {
String value();
}
仿照GET方法注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AnnotationGet {
String value();
}
通过动态代理实现注解和数据拼装
public class RetrofitCopy {
public <T> T create(final Class<T> service) {
return (T) Proxy.newProxyInstance(
service.getClassLoader(),
new Class[]{service},
new AssemblyParametersInvocationHandler()
);
}
private class AssemblyParametersInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
StringBuilder builder = new StringBuilder();
for (Annotation annotation : method.getAnnotations()) {
if (annotation instanceof AnnotationGet) {
AnnotationGet get = (AnnotationGet) annotation;
builder.append(get.value());
}
}
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
for (Annotation annotation : parameter.getAnnotations()) {
builder.append(getParementerAnnotationValue(annotation));
builder.append("=");
}
builder.append(args[i]);
if (i < parameters.length - 1) {
builder.append("?");
}
}
Log.e("RetrofitCopy", "net: " + builder.toString());
return null;
}
}
private String getParementerAnnotationValue(Annotation annotation) {
String data = "";
if (annotation instanceof AnnotationField) {
AnnotationField field = (AnnotationField) annotation;
return field.value();
}
return data;
}
}
创建接口api
public interface Api {
@AnnotationGet("http://baidu.com/")
void getData(
@AnnotationField("name")
String name,
@AnnotationField("age") int age
);
}
执行调用代码
val api = RetrofitCopy().create(Api::class.java);
api.getData("copyNet1", 1000);
api.getData("copyNet2", 2000);
api.getData("copyNet3", 3000);
api.getData("copyNet4", 4000);
api.getData("copyNet5", 5000);
api.getData("copyNet6", 6000);
api.getData("copyNet7", 7000);
打印数据如下
这个就是retrofit封装参数的原理,是不是和retrofit一样,只需要接口,然后接口调用方法就可以了