RetrofitClient:用于activity直接交互
public class RetrofitClient {
private final static ServiceApi mServiceApi;
static {
OkHttpClient okHttpClient = new OkHttpClient
.Builder().addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.e("TAG", message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://app.ahhuabang.com:8088/server/index.php/user/")
.client(okHttpClient)
.build();
mServiceApi = retrofit.create(ServiceApi.class);
}
public static ServiceApi getServiceApi() {
return mServiceApi;
}
}
ServiceApi接口
public interface ServiceApi {
@GET("is_login")
Call<UserLoginResult> userlogin(@Query("username") String userName, @Query("password") String password);
}
UserLoginResult结果进行封装
public class UserLoginResult {
private String msg;
private String token;
@Override
public String toString() {
return "UserInfo{" +
"msg='" + msg + '\'' +
", token='" + token + '\'' +
'}';
}
}
定义三个接口:GET,POST,QUERY
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GET {
String value();
}
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Query {
String value();
}
创建Retrofit
public class Retrofit {
String baseUrl;
okhttp3.Call.Factory callFactory;
private Map<Method,ServiceMethod> serviceMethodMapCache=new ConcurrentHashMap<>();
public Retrofit(Builder builder) {
baseUrl=builder.baseUrl;
callFactory=builder.callFactory;
}
//动态代理对象
public <T> T create(Class<T> service) {
return (T) Proxy.newProxyInstance(service.getClassLoader(),
new Class[]{service},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//args是测试专用和HB654321
if(method.getDeclaringClass()==Object.class){
return method.invoke(this,args);
}
//解析参数注解@Query("username") String userName, @Query("password") String password
ServiceMethod serviceMethod= loadServiceMethod(method);
OkHttpCall okHttpCall=new OkHttpCall(serviceMethod,args);
return okHttpCall;
}
});
}
//@Query("username") String userName, @Query("password") String password
private ServiceMethod loadServiceMethod(Method method) {
// 享元设计模式
ServiceMethod serviceMethod = serviceMethodMapCache.get(method);
if(serviceMethod==null){
serviceMethod=new ServiceMethod.Builder(this,method).build();
serviceMethodMapCache.put(method,serviceMethod);
}
return serviceMethod;
}
public static class Builder {
String baseUrl;
okhttp3.Call.Factory callFactory;
public Builder baseUrl(String baseUrl) {
this.baseUrl = baseUrl;
return this;
}
public Builder client(okhttp3.Call.Factory callFactory) {
this.callFactory=callFactory;
return this;
}
public Retrofit build() {
if(callFactory==null){
callFactory=new OkHttpClient();
}
return new Retrofit(this);
}
}
}
ServiceMethod方法的入口
public class ServiceMethod {
final Retrofit retrofit;
final Method method;
//GET,POST的字符串
String httpMethod;
//相对路径
String relativeUrl;
final ParameterHandler<?>[] parameterHandlers;
public ServiceMethod(Builder builder) {
this.retrofit = builder.retrofit;
this.method = builder.method;
this.httpMethod = builder.httpMethod;
this.relativeUrl = builder.relativeUrl;
this.parameterHandlers = builder.parameterHandlers;
}
//根据参数创建一个Call
public Call createNewCall(Object[] args) {
RequestBuilder requestBuilder = new RequestBuilder(retrofit.baseUrl, relativeUrl,
httpMethod, parameterHandlers, args);
return retrofit.callFactory.newCall(requestBuilder.build());
}
//将response
public <T> T parseBody(ResponseBody response) {
// 获取解析类型 T 获取方法返回值的类型
Type returnType = method.getGenericReturnType();//返回值对象 Call<UserLoginResult>
//获得泛型的类
Class<T> dataClass = (Class<T>) ((ParameterizedType) returnType).getActualTypeArguments()[0];
Gson gson = new Gson();
T body = gson.fromJson(response.charStream(), dataClass);
return body;
}
public static class Builder {
final Retrofit retrofit;
final Method method;
//获得所有的方法注解
final Annotation[] methodAnnotations;
//GET,POST的字符串
String httpMethod;
//相对路径
String relativeUrl;
//获得所有参数注解
final Annotation[][] parameterAnnotations;
final ParameterHandler<?>[] parameterHandlers;
public Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
methodAnnotations = method.getDeclaredAnnotations();
parameterAnnotations = method.getParameterAnnotations();
parameterHandlers = new ParameterHandler[parameterAnnotations.length];
}
public ServiceMethod build() {
// 解析,OkHttp 请求的时候 ,url = baseUrl + relativeUrl,relativeUrl注解get和post
for (Annotation methodAnnotation : methodAnnotations) {
parseAnnotationMethod(methodAnnotation);
}
// 解析参数注解
int count = parameterAnnotations.length;
for (int i = 0; i < count; i++) {
//@Query("username") String userName, @Query("password") String password
//@Query("username")
Annotation parameter = parameterAnnotations[i][0];
//@Query @QueryMap
if (parameter instanceof Query) {
//将username和password进行封装
parameterHandlers[i] = new ParameterHandler.Query<>(((Query) parameter).value());
}
}
return new ServiceMethod(this);
}
/**
* 解析get和post
*
* @GET("is_login")
*/
private void parseAnnotationMethod(Annotation methodAnnotation) {
if (methodAnnotation instanceof GET) {
parseMethodAndPath("GET", ((GET) methodAnnotation).value());
} else if (methodAnnotation instanceof POST) {
parseMethodAndPath("POST", ((POST) methodAnnotation).value());
}
}
private void parseMethodAndPath(String methodName, String value) {
this.httpMethod = methodName;
this.relativeUrl = value;
}
}
}
ParameterHandler保存内部注解参数
public interface ParameterHandler<T> {
void apply(RequestBuilder requestBuilder, T value);
public class Query<T> implements ParameterHandler<T> {
private String key; // 保存 就是参数的 key = userName ,password
public Query(String key){
this.key = key;
}
@Override
public void apply(RequestBuilder requestBuilder, T value) {
requestBuilder.addQueryName(key, value.toString());
}
}
}
OkHttpCall将内部参数和GET、POST的参数封装
public class OkHttpCall<T> implements Call<T> {
final ServiceMethod serviceMethod;
final Object[] args;//自己传入的值
//serviceMethod封装
public OkHttpCall(ServiceMethod serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
//执行异步方法
@Override
public void enqueue(final Callback<T> callback) {
Log.e("TAG", "正式发起请求");
okhttp3.Call call = serviceMethod.createNewCall(args);
call.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
if (callback != null) {
callback.onFailure(OkHttpCall.this, e);
}
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
Response rResponse = new Response();
//这里将response.body转换成Gson对象
rResponse.body= serviceMethod.parseBody(response.body());
if(callback!=null){
callback.onResponse(OkHttpCall.this,rResponse);
}
}
});
}
}
Call只有一个异步的方法
public interface Call<T> {
void enqueue(Callback<T> callback);
}
Callback结果回调
public interface Callback<T> {
void onResponse(Call<T> call, Response<T> response);
void onFailure(Call<T> call, Throwable t);
}
RequestBuilder生成OKhttp的request
public class RequestBuilder {
HttpUrl.Builder httpUrl;
ParameterHandler<Object>[] parameterHandlers;
Object[] args;
public RequestBuilder(String baseUrl, String relativeUrl
, String httpMethod, ParameterHandler<?>[] parameterHandlers, Object[] args) {
httpUrl=HttpUrl.parse(baseUrl+relativeUrl).newBuilder();
this.parameterHandlers= (ParameterHandler<Object>[]) parameterHandlers;
this.args=args;
}
//key 是username,password,自己传入的值
public void addQueryName(String key, String value) {
httpUrl.addQueryParameter(key,value);
}
public Request build() {
//传入值
int length = args.length;
for (int i = 0; i < length; i++) {
parameterHandlers[i].apply(this,args[i]);
}
Request request=new Request.Builder().
url(httpUrl.build()).build();
return request;
}
}
Response结果
public class Response<T> {
public T body;
}
测试
Call<UserLoginResult> call = RetrofitClient.getServiceApi().userlogin("测试专用", "HB654321");
call.enqueue(new Callback<UserLoginResult>() {
@Override
public void onResponse(Call<UserLoginResult> call, Response<UserLoginResult> response) {
Log.e("TAG",response.body.toString());
}
@Override
public void onFailure(Call<UserLoginResult> call, Throwable t) {
}
});