手写retrofit

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24675479/article/details/79846282

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) {

            }
        });

猜你喜欢

转载自blog.csdn.net/qq_24675479/article/details/79846282
今日推荐