1.定义注解:
@Get注解,用来定义网络请求类型
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Get {
String value();
}
@Queue注解用定义请求参数名
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Queue {
String value();
}
2.定义网络请求接口:
public class NetInterface {
@Get("person/search?")
Call<Person> getPerson(@Queue("index") int index, @Queue("page") int page);
}
3.访问网络的接口及回调:
public interface Call<T> {
void call(String call);
void enqueue(Callback<T> callback);
}
public interface Callback<T> {
void onResponse(Call<T> call, Response<T> response);
void onFailure(Call<T> call, Throwable t);
}
网络请求的实现类:伪代码
public class RealCall implements Call {
public void call(String call){
System.out.println("realcall "+call);
}
@Override
public void enqueue(Callback callback) {
}
}
4.Retrofit实现网络请求的核心代码:
public class Retrofit {
String url;
public Retrofit(String url) {
this.url = url;
}
public static final class Builder {
String url;
Builder() {
}
//通过构造者模式创建Retrofit对象
public Retrofit build() {
return new Retrofit(this.url);
}
public Builder baseUrl(String url) {
this.url = url;
return this;
}
}
public <T> T create(Class<T> service) {
//通过泛型类,接收不同的接口Class对象,通过动态代理,来创建不同接口的代理对象
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
try{
//method 是代理对象调用的方法名
//args 是代理对象调用方法时传递的参数
//解析方法中定义的注解和参数,用来拼接完整的url请求
parseMethod(method, args);
}catch (Exception e){
e.printStackTrace();
}
//返回一个真正的网络请求对象,里面包含网络请求的url。
return new RealCall();
}
});
}
private void parseMethod(Method method, Object[] args) {
//@Get("person/search?")
//Call<Person> getPerson(@Queue("index") int index, @Queue("page") int page);
//拿到方法中定义的注解
Annotation[] ans = method.getAnnotations();
for (Annotation an : ans) {
if (an instanceof Get) {
Get get = (Get) an;
//拿到注解中写入的value值 person/search?
String value = get.value();
}
}
//通过方法拿到方法参数中定义的注解,有多个参数
Annotation[][] annotations = method.getParameterAnnotations();
for (Annotation[] ans2 : annotations) {
for (Annotation an : ans2) {
if (an instanceof Queue) {
Queue queue = (Queue) an;
//拿到value值 index page
String value = queue.value();
}
}
}
//解析动态代理对象调用方法时传递的参数。
for (int i = 0; i < args.length; i++) {
int arg = (int) args [i];
System.out.println(arg);
}
//通过以上解析拿到的数据,就可以拼接成一个完整的url请求。
//baseUrl+person/search?index=1&page=1;
}
}
5.客户端通过Retrofit 发起网络请求:
//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.baidu.com/")
.build();
//调用create方法,返回NetInterface的动态代理类。
NetInterface netInterface = retrofit.create(NetInterface.class);
//根据InvocationHandler中invoke方法中的返回值,拿到发起网络请求的对象。
Call<Person> call = netInterface.getPerson(1,2);
//加入网络请求队列,发起网络请求。
call.enqueue(new Callback<Person>() {
//请求回调
@Override
public void onResponse(Call<Person> call, Response<Person> response) {
}
@Override
public void onFailure(Call<Person> call, Throwable t) {
}
});
6.Retrofit中主要用到了动态代理、反射、注解。还有一些设计模式:构造者模式等,以后再做详细分析。