手写Retrofit Get请求(支持Rxjava)

2018-11-20  本文已影响0人  小熊_c37d

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<WeatherData> call = weather.getWeather("杭州");
    call.enqueue(new Callback<WeatherData>() {
        @Override
        public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {
            Log.i(TAG, "onResponse: " + new Gson().toJson(response.body()));
        }

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

        }
    });
}
interface Weather {
    @GET("weatherApi")
    Call<WeatherData> 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<WeatherData> call = weather.getWeather("杭州");
    call.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<WeatherData>() {
                @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<WeatherData> dataCall = weather.getWeather1("南京");
    dataCall.enqueue(new Callback<WeatherData>() {
        @Override
        public void onResponse(Call<WeatherData> call, IResponse<WeatherData> response) {
            WeatherData.DataBean data = response.body.getData();
            Log.i(TAG, "onResponse: " + data.getCity());
        }

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

        }
    });

}

interface Weather {
    @GET("weatherApi")
    Observable<WeatherData> getWeather(@Query("city") String string);
    @GET("weatherApi")
    Call<WeatherData> 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<Method, ServiceMethod> 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> 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> 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<R, T> {
    //请求类型 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<R, T> 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<R, T>) 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<T> 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<T> implements Call<T> {
    final ServiceMethod serviceMethod;
    final Object[] args;//自己传入的值

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

    @Override
    public void enqueue(final Callback<T> 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<T> execute() {
        okhttp3.Call call = serviceMethod.toCall(args);
        try {
            IResponse objectResponse = new IResponse<>();
            objectResponse.body=parseBody(call.execute().body());
            return (IResponse<T>) objectResponse;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


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

Call

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

CallAdapter

public interface CallAdapter<R, T> {

    T adapt(Call<R> call);

    abstract class Factory {
        public abstract CallAdapter<?, ?> get();
    }
}

Callback

public interface Callback<T> {

    void onResponse(Call<T> call, IResponse<T> response);

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

DefaultCallAdapterFactory 默认的callAdapter

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

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

RxJava2CallAdapterFactory 支持rxjava的callAdapter

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



public class RxJava2CallAdapter implements CallAdapter<Object,Object> {


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

final class CallObservable<T> extends Observable<T> {
    private final Call<T> originalCall;

    CallObservable(Call<T> originalCall) {
        this.originalCall = originalCall;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        IResponse<T> response = originalCall.execute();
        T body = response.body;
        observer.onNext(body);
        observer.onComplete();
    }
}
上一篇下一篇

猜你喜欢

热点阅读