Retrofit 自定义ConverterFactory

想不想让网络请求变得可控?想不想让网络请求变得更加简单?有句话说得好,不会偷懒的程序员就不是一个好程序员。那如何偷懒呢?以retrofit网络请求为例,对retrofit网络请求进行自定义ConverterFactory封装使用。不足之处,请大佬不吝赐教。

1、Retrofit介绍

Retrofit是对网络请求框架的封装。需要说明的是Retrofit不是网络请求框架,是因为Retrofit的网络请求是交给OkHttp完成的。Retrofit只专注于对请求接口的封装。Retrofit的出现是网络请求接口定义与使用分离开来,是代码更加简练,同时灵活的http client配置以及支持多种返回数据解析的Converter配置可以快速进行数据转换等功能,是项目中的网络请求变得更加简单。

2、Retrofit使用

Retrofit使用网上已经有很多的案例,这里我不做深入分析,在这里我简单介绍一下retrofit的使用。

a) 创建OkHttpClient对象

        client = new OkHttpClient.Builder()
            .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            .readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            //添加日志打印拦截器
            .addInterceptor(new LoggerInterceptor(Constant.LOGISHOW))
            .addInterceptor(new TokenInterceptor())
            .retryOnConnectionFailure(true)
            .build();

b) 创建Retrofit对象

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

c) 定义Service接口

public interface ApiService {
    @GET("weather_mini")
    Call<Login> requesntLoat(@QueryMap HashMap<String,String>params);
}

d)获取Call对象,并执行请求,获取网络数据

ApiService mService= ApiRetroift.build().create(ApiService.class);
Call<Login> call = mService.requesntLoat(params);
call.enqueue(new Callback<Login>() {
    @Override
    public void onResponse(Call<Login> call, Response<Login> response) {

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

    }
});

  上面是对retrofit的简单实用,如果项目中功能不多,网络请求也不很负责情况下,这样写已经完全满足需求了。但我们实际项目开发中,一般会用到几十甚至上千个网络请求,如果对每个网络请求都单独处理,势必会增加我们很多工作量。我们需要对这些网络请求统一处理,对网络数据和可能的异常统一拦截处理。下面我们通过自定义ConverterFactory对网络实现统一异常处理。

3、Retrofit 自定义ConverterFactory

a) 创建适配器工厂

创建ApiCallAdapterFactory类并继承CallAdapter.Factory,作为Retrofit返回的新工厂。这里继承CallAdapter.Factory类,需要重写Factory的get方法,而get方法的返回对象决定了你将采取什么样的CallAdapter对象。

public class ApiCallAdapterFactory extends CallAdapter.Factory  {
    @Nullable
    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        return null;
    }
}

下面是对get方法的重写

@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class && getRawType(returnType) != Observable.class) {
        return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
        throw new IllegalArgumentException(
                "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
    }
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

    final Executor executor =
            Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
                    ? null
                    : callbackExecutor;
    if (getRawType(responseType) == Call.class){
        return new CallAdapter<Object, Call<?>>() {
            @Override
            public Type responseType() {
                return responseType;
            }

            @Override
            public Call<Object> adapt(Call<Object> call) {
                return executor == null ? call : new DefaultExecutorCallbackCall<>(executor, call);
            }
        };
    }else{
        return new ApiCallAdapter<>(responseType,executor);
    }
}

这里为了不破坏定义Service返回的原有的Call对象,这里我只做了增量返回。就是监测方法的返回值类型如果是Call.class,则我们继续返回Retrofit默认的     DefaultExecutorCallbackCall对象,如果是我们自己申明的Observable.class,则返回我们自定义的ApiCallAdapter对象。

b) 定义Observable接口,作为Service中方法的返回类型

public interface Observable<R>{
    /*取消请求*/
    void  cancel();
     /*关联监听对象,并发起请求*/
    void subscribeWith(ApiObserver<R> observe);
    /*关联监听时间*/
    void detection(Disposable disposable);
    /*判断是否已执行*/
    boolean isExecuted();
    /*克隆当前请求对象 clone*/
    Observable<R> clone();
    /** The original HTTP request. */
    Request request();
    /*timeout*/
    Timeout timeout();
}

c)创建EnqueueObservable类,并实现Observable<R>接口

public class EnqueueObservable<R> implements Observable<R> {
    private final Call<R> call;
    private final Executor callbackExecutor;
    private Disposable mDisposable;


    public EnqueueObservable(Call<R> call, Executor callbackExecutor) {
        this.call = call;
        this.callbackExecutor = callbackExecutor;
    }
    ...
}

其中在重写的subscribeWith中,完成对网络请求的发起和对请求返回的数据及可能的异常统一处理

@Override
public synchronized void subscribeWith(ApiObserver<R> observe) {
    Objects.requireNonNull(observe, "observe == null");
    observe.onStart();
    call.enqueue(new Callback<R>() {
        @Override
        public void onResponse(Call<R> call, final Response<R> response) {
            if (call.isCanceled()) {
                observe.onFailure(new ApiException(-1,"Canceled"));
            } else {
                int code = response.code();
                if (200<=code && code <=299){
                    observe.onNext(response.body());
                }else{
                    observe.onFailure(new ApiException(code,response.message()));
                }
            }
            observe.onFinish();
        }
        @Override
        public void onFailure(Call<R> call, final Throwable t) {
            observe.onFailure(ExceptionHelper.transformException(t));
            observe.onFinish();
        }
    });
}

其中ApiException是我们定义网络请求异常类

public class ApiException {
    private int code;
    private String message;
    public ApiException(int code, String message) {
        this.code = code;
        this.message = message;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

ApiObserver是用来监听网络请求的回调类

public interface ApiObserver<R>{
    void onStart();
    void onNext(R data);
    void onFailure(ApiException t);
    void onFinish();
}

4、使用自定义的ApiCallAdapterFactory工厂

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory( ApiCallAdapterFactory.create())
                .build();

a) 自定义Observable接口的使用

public interface ApiService {
    @GET("weather_mini")
    Observable<Login> requesntLoat(@QueryMap HashMap<String,String>params);
}

5、创建NetDisposable类,对网络请求进行统一管理

NetDisposable类是为了统一管理网络请求,防止页面销毁网络请求还在继续执行的问题。当Activity或者Fragment销毁的时候,在onDestory会调用中触发NetDisposable的disposeAll方法,取消所有网路请求。

public class NetDisposable {

    LinkedList<Observable>mObservables;
    public void dispose() {
        for (int i = 0; i < mObservables.size(); i++) {
            Observable ob = mObservables.get(i);
            if (ob.isExecuted()){
                mObservables.remove(ob);
                i--;
            }
        }
    }

    public void add(Observable observable){
        if (null == mObservables){
            mObservables = new LinkedList<>();
        }
        observable.detection(new Disposable() {
            @Override
            public void dispose() {
                NetDisposable.this.dispose();
            }
        });
        mObservables.add(observable);
    }

    public void disposeAll(){
        for (Observable ob:mObservables) {
            ob.cancel();
        }
        mObservables.clear();
    }
}

6、结合MVP模式,创建ApiPresenter类,并在ApiPresenter中统一发送请求,让请求变得更简单。使用是只需要让我们的BasePresenter类继承ApiPresenter

public class ApiPresenter {

    private NetDisposable mDisposable;

    /*接触绑定,同时取消网络请求*/
    public void deteachView() {
        removeDispose();
    }

    public <T> void sendRequest(Observable<T> observable, ResultBack observer) {
        if (null == mDisposable){
            mDisposable = new NetDisposable();
        }
        mDisposable.add(observable);
        observable.subscribeWith(observer);
    }

    private void removeDispose() {
        if (null != mDisposable ) {
            mDisposable.disposeAll();
        }
    }
}

7、创建ResultBack类,让回调变得更简单

public abstract class ResultBack<T> implements ApiObserver<T> {
    private final String TAG = "Api";
    Context context;
    public ResultBack(Context context){
        this.context = context;
    }

    @Override
    public void onStart() {
        //请求开始
    }

    @Override
    public void onNext(T data) {
        //接收到数据
        onSuccess(data);
    }
    @Override
    public void onFailure(ApiException t) {
        Log.i(TAG,"=========================="+ t.getMessage());
        onFaild(t.getCode(),t.getMessage());
    }
    @Override
    public void onFinish() {
        //请求结束
    }
    public abstract void onSuccess(T data);
    public abstract void onFaild(int code,String message);
}

8、在MVP的P层中发起请求

public void requestLogin(Context context){
    HashMap<String,String>params = new HashMap<>();
    params.put("city","沈阳");
    sendRequest(mService.requesntLoat(params),new ResultBack<Login>(context){
        @Override
        public void onSuccess(Login data) {
            Log.d("API", "onSuccess: ======="+data.toString());
        }

        @Override
        public void onFaild(int code, String message) {

        }
    });
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值