手写Retrofit Get请求(支持Rxjava)

Retrofit2 简单介绍

简单的说就是一个网络请求的适配器,它将一个基本的Java接口通过动态代理的方式翻译成一个HTTP请求,并通过OkHttp去发送请求。更具体自行搜索

public void getWeather() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://www.apiopen.top/")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    Weather weather = retrofit.create(Weather.class);
    Call call = weather.getWeather("杭州");
    call.enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) {
            Log.i(TAG, "onResponse: " + new Gson().toJson(response.body()));
        }

        @Override
        public void onFailure(Call call, Throwable t) {

        }
    });
}
interface Weather {
    @GET("weatherApi")
    Call getWeather(@Query("city") String string);
}

手写调用

    Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.apiopen.top/").callAdapter(new RxJava2CallAdapterFactory()).build();
    Weather weather = retrofit.create(Weather.class);
    Observable call = weather.getWeather("杭州");
    call.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(WeatherData data) {
                    Log.i(TAG, "onNext: " + data.getData().getCity());
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
    Call dataCall = weather.getWeather1("南京");
    dataCall.enqueue(new Callback() {
        @Override
        public void onResponse(Call call, IResponse response) {
            WeatherData.DataBean data = response.body.getData();
            Log.i(TAG, "onResponse: " + data.getCity());
        }

        //
        @Override
        public void onFailure(Call call, Throwable t) {

        }
    });

}

interface Weather {
    @GET("weatherApi")
    Observable getWeather(@Query("city") String string);
    @GET("weatherApi")
    Call getWeather1(@Query("city") String string);
}

创建Get请求需要的注解 Get ,Query

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GET {
    String  value();
}

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Query {
    String value() default "";
}

创建Retrofit 通过Builder 初始化参数

public class Retrofit {
    private HttpUrl baseUrl;
    private okhttp3.Call.Factory callFactroy;
    private ConcurrentHashMap serviceMethodCache;
    private CallAdapter.Factory callAdapter;

    public Retrofit(Builder builder) {
        serviceMethodCache = new ConcurrentHashMap<>();
        baseUrl = builder.baseUrl;
        callFactroy = builder.callFactroy;
        callAdapter = builder.callAdapter;
    }

    public HttpUrl getBaseUrl() {
        return baseUrl;
    }

    public okhttp3.Call.Factory callFactroy() {
        return callFactroy;
    }

    public CallAdapter.Factory callAdapter() {
        return callAdapter;
    }


    public  T create(final Class service) {
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                ServiceMethod serviceMethod =  loadServiceMethod(method);
                OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
                return serviceMethod.adapt(okHttpCall);
            }
        });

    }

    //缓存查找ServiceMethod
    private ServiceMethod loadServiceMethod(Method method) {
        //从缓存里获取
        ServiceMethod serviceMethod = serviceMethodCache.get(method);
        if (null == serviceMethod) {
            //缓存没有取到 创建ServiceMethod 并缓存
            serviceMethod = new ServiceMethod.Builder(this, method).build();
            serviceMethodCache.put(method, serviceMethod);
        }
        return serviceMethod;

    }


    /**
     * 构建着模式
     */
    public static final class Builder {

        private HttpUrl baseUrl;
        private okhttp3.Call.Factory callFactroy;
        private CallAdapter.Factory callAdapter;

        public Builder baseUrl(String baseUrl) {
            this.baseUrl = HttpUrl.parse(baseUrl);
            return this;
        }

        public Builder callFactroy(okhttp3.Call.Factory callFactroy) {
            this.callFactroy = callFactroy;
            return this;
        }

        public Builder callAdapter(CallAdapter.Factory factory) {
            this.callAdapter = factory;
            return this;
        }

        public Retrofit build() {
            if (null == baseUrl) {
                throw new IllegalArgumentException("HttpUrl not set");
            }
            if (null == callFactroy) {
                callFactroy = new OkHttpClient();
            }
            return new Retrofit(this);
        }

    }
}

Weather weather = retrofit.create(Weather.class); 我们可以看到这里通过Proxy.newProxyInstance 代理了这个接口,里面做了三件事情 loadServiceMethod(method);缓存查找 loadServiceMethod(method);创建OkHttpCall ,serviceMethod.adapt(okHttpCall)拿到需要的call

public  T create(final Class service) {
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            ServiceMethod serviceMethod =  loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
            return serviceMethod.adapt(okHttpCall);
        }
    });

}

ServiceMethod

public class ServiceMethod {
    //请求类型 POST   GET
    private String httpMethod;
    //请求的地址 不包含baseUrl;
    private String mRelativeUrl;

    private ParameterHandler[] mParameterHandler;
    private final Retrofit mRetrofit;
    private HttpUrl.Builder mUrlBuilder;
    private final okhttp3.Call.Factory mCallFactroy;
    private FormBody.Builder mFormBody;
    private RequestBody mRequestBody;
    private Method mMethod;
    private CallAdapter callAdapter;

    public ServiceMethod(Builder builder) {
        mMethod = builder.mMethod;
        mRetrofit = builder.mRetrofit;
        httpMethod = builder.httpMethod;
        mRelativeUrl = builder.mRelativeUrl;
        mParameterHandler = builder.mParameterHandler;
        mCallFactroy = mRetrofit.callFactroy();
        callAdapter = (CallAdapter) mRetrofit.callAdapter().get();
    }

    public Method getMethod() {
        return mMethod;
    }

    public Call toCall(Object[] args) {
        //创建Okhttp Request
        Request.Builder requestBuilder = new Request.Builder();
        //确定地址请求地址
        if (mUrlBuilder == null) {
            mUrlBuilder = mRetrofit.getBaseUrl().newBuilder(mRelativeUrl);
        }
        for (int i = 0; i < mParameterHandler.length; i++) {
            mParameterHandler[i].appley(this, String.valueOf(args[i]));
        }
        requestBuilder.url(mUrlBuilder.build());
        requestBuilder.method(httpMethod, null);
        Request request = requestBuilder.build();
        return mCallFactroy.newCall(request);
    }

    //get请求Query 注解
    public void addQueryParameter(String name, String value) {
        mUrlBuilder.addQueryParameter(name, value);
    }

  



    public T adapt(Call call) {
        Type genericReturnType = mMethod.getGenericReturnType();
        Class rawType = getRawType(genericReturnType);
         //判断方法返回类型 是Call 直接用默认的callAdapter         
        if (rawType == Call.class) {
            return (T) DefaultCallAdapterFactory.INSTANCE.get().adapt(call);
        }
        //使用传入的RxJava2CallAdapterFactory 
        return callAdapter.adapt(call);
    }

    Class getRawType(Type type) {
        checkNotNull(type, "type == null");

        if (type instanceof Class) {
            // Type is a normal class.
            return (Class) type;
        }
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;

            // I'm not exactly sure why getRawType() returns Type instead of Class. Neal isn't either but
            // suspects some pathological case related to nested classes exists.
            Type rawType = parameterizedType.getRawType();
            if (!(rawType instanceof Class)) throw new IllegalArgumentException();
            return (Class) rawType;
        }
        if (type instanceof GenericArrayType) {
            Type componentType = ((GenericArrayType) type).getGenericComponentType();
            return Array.newInstance(getRawType(componentType), 0).getClass();
        }
        if (type instanceof TypeVariable) {
            // We could use the variable's bounds, but that won't work if there are multiple. Having a raw
            // type that's more general than necessary is okay.
            return Object.class;
        }
        if (type instanceof WildcardType) {
            return getRawType(((WildcardType) type).getUpperBounds()[0]);
        }

        throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
                + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
    }

    public static final class Builder {

        private final Annotation[] mMethodAnnotations;
        private final Annotation[][] mParameterAnnotations;
        private final Retrofit mRetrofit;
        //请求类型 POST   GET
        private String httpMethod;
        //请求的地址 不包含baseUrl;
        private String mRelativeUrl;

        private ParameterHandler[] mParameterHandler;


        private Method mMethod;

        public Builder(Retrofit retrofit, Method method) {
            mMethod = method;
            mRetrofit = retrofit;
            //拿到该方法注解
            mMethodAnnotations = method.getAnnotations();
            //拿到方法注解
            mParameterAnnotations = method.getParameterAnnotations();

        }

        public ServiceMethod build() {
            //处理方法注解
            for (Annotation methodAnnotation : mMethodAnnotations) {
                paresMethodAnnotation(methodAnnotation);
            }
            paresParameterAnnotation();
            return new ServiceMethod(this);
        }

        private void paresMethodAnnotation(Annotation methodAnnotation) {
            if (methodAnnotation instanceof GET) {
                httpMethod = "GET";
                GET get = (GET) methodAnnotation;
                mRelativeUrl = get.value();
            } 

        }

        private void paresParameterAnnotation() {
            //处理参数
            mParameterHandler = new ParameterHandler[mParameterAnnotations.length];
            for (int i = 0; i < mParameterAnnotations.length; i++) {
                Annotation[] parameterAnnotation = mParameterAnnotations[i];
                //遍历一个参数上的所有注解
                for (Annotation annotation : parameterAnnotation) {
                    if (annotation instanceof Query) {
                        Query query = (Query) annotation;
                        String value = query.value();
                        mParameterHandler[i] = new ParameterHandler.Query(value);
                    }
                }
            }
        }
    }
}

ParameterHandler

public abstract class ParameterHandler {

    abstract void appley(ServiceMethod method, String value);


    static class Query extends ParameterHandler {

        private final String mName;

        public Query(String name) {
            this.mName = name;
        }

        @Override
        void appley(ServiceMethod method, String value) {
            method.addQueryParameter(mName, value);
        }
    }   
}

OkHttpCall

public class OkHttpCall implements Call {
    final ServiceMethod serviceMethod;
    final Object[] args;//自己传入的值

    public OkHttpCall(ServiceMethod serviceMethod, Object[] args) {
        this.serviceMethod = serviceMethod;
        this.args = args;
    }

    @Override
    public void enqueue(final Callback callback) {
        okhttp3.Call call = serviceMethod.toCall(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, Response response) throws IOException {
                IResponse rResponse = new IResponse();
                rResponse.body = parseBody(response.body());
                if (callback != null) {
                    callback.onResponse(OkHttpCall.this, rResponse);
                }
            }
        });

    }

    @Override
    public IResponse execute() {
        okhttp3.Call call = serviceMethod.toCall(args);
        try {
            IResponse objectResponse = new IResponse<>();
            objectResponse.body=parseBody(call.execute().body());
            return (IResponse) objectResponse;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public  T parseBody(ResponseBody response) {
        Type returnType = serviceMethod.getMethod().getGenericReturnType();
        Class dataClass = (Class) ((ParameterizedType) returnType).getActualTypeArguments()[0];
        Gson gson = new Gson();
        T body = gson.fromJson(response.charStream(), dataClass);
        return body;
    }
}

Call

public interface Call {
    void enqueue(Callback callback);
    IResponse execute();
}

CallAdapter

public interface CallAdapter {

    T adapt(Call call);

    abstract class Factory {
        public abstract CallAdapter get();
    }
}

Callback

public interface Callback {

    void onResponse(Call call, IResponse response);

    void onFailure(Call call, Throwable t);
}
public final  class IResponse {
    public T body;
}

DefaultCallAdapterFactory 默认的callAdapter

public class DefaultCallAdapterFactory extends CallAdapter.Factory {
    public static DefaultCallAdapterFactory INSTANCE = new DefaultCallAdapterFactory();

    @Override
    public CallAdapter get() {
        return new CallAdapter() {
            @Override
            public Object adapt(Call call) {
                return call;
            }
        };
    }
}
 
 

RxJava2CallAdapterFactory 支持rxjava的callAdapter

public class RxJava2CallAdapterFactory extends CallAdapter.Factory {
    @Override
    public CallAdapter get() {
        return new RxJava2CallAdapter();
    }
}



public class RxJava2CallAdapter implements CallAdapter {


    @Override
    public Object adapt(Call call) {
        Observable responseObservable = new CallObservable<>(call);
        return responseObservable;
    }
}

final class CallObservable extends Observable {
    private final Call originalCall;

    CallObservable(Call originalCall) {
        this.originalCall = originalCall;
    }

    @Override
    protected void subscribeActual(Observer observer) {
        IResponse response = originalCall.execute();
        T body = response.body;
        observer.onNext(body);
        observer.onComplete();
    }
}
 

                            
                        
                    
                    
                    

你可能感兴趣的:(手写Retrofit Get请求(支持Rxjava))