Retrofit封装

Retrofit+OKHttp+MVP的Android架构已经火了很久了,我自己也使用了有一段时间,但由于一直忙于这样或那样的事,一直没有做相关的笔记。年底先来无事,又重新看一了一遍相关的资料,做点笔记(好记性不如烂笔头)。
这里写图片描述

使用到的开发模式:
1.单利
2.建造者

使用的相关库:

    //网络请求依赖
    compile 'com.squareup.okio:okio:1.13.0'
    compile 'com.squareup.okhttp3:okhttp:3.8.1'
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-scalars:2.3.0'

第一步:先使用Retrofit最基本的用法
1.创建对应的API接口

public interface ApiService {
    @GET
    Call<String> get(@Url String url, @QueryMap WeakHashMap<String, Object> params);
}

使用WeakHashMap的原因是该容器使用的是弱引用有利于gc回收。

2.在需要访问的Activity类中添加访问请求代码:

      private void netTest1(){
        //Retorfit对象
        Retrofit retrofit=new Retrofit.Builder()
                .client(new OkHttpClient())
                .baseUrl("https://www.baidu.com/")
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();
        //接口
        ApiService apiService=retrofit.create(ApiService.class);
        Call<String> call=apiService.get("",new WeakHashMap<String, Object>());
        //发起网络请求
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                if (response.isSuccessful()){
                    Toast.makeText(getApplicationContext(),response.body(),Toast.LENGTH_LONG).show();
                }
            }

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

            }
        });
    }

Retrofit创建对象的时候需要添加
Http通信类:OkHttp
基本网络地址:baseUrl(如果一个项目有多个不一样的主Host会很蛋疼),并且要反斜杠结束
ResponseBody返回类型:ScalarsConverterFactory(字符串)

3.调用:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        netTest1();
    }

结果如下:
这里写图片描述

可以看到访问百度地址请求已经成功了!

很显然,每次调用网络的时候我们都需要重复写这段代码。
那就的做法是写个Utils吧(一般做法)。
这里写图片描述

第二步:抽出一个Utils调用
1.编写utils工具类

public class RetorfitUtils {
    public static void request(String url, WeakHashMap<String,Object> params,Callback callback){
        //Retorfit对象
        Retrofit retrofit=new Retrofit.Builder()
                .client(new OkHttpClient())
                .baseUrl("https://www.baidu.com/")
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();
        //接口
        ApiService apiService=retrofit.create(ApiService.class);
        Call<String> call=apiService.get(url,new WeakHashMap<String, Object>());
        //发起网络请求
        call.enqueue(callback);
    }

}

2.Activity调用

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WeakHashMap<String,Object> params=new WeakHashMap<>();
        RetorfitUtils.request("", params, new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                if (response.isSuccessful()){
                    Toast.makeText(getApplicationContext(),response.body(),Toast.LENGTH_LONG).show();
                }
            }

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

            }
        });
    }

结果:
可以看到结果与上面一致。

仔细想想,这个Utils工具类只是将我们经常调用请求代码抽出来,方便使用但代码的运行效率并没有得到优化。发起多个网络请求还是会多次实例化Retorfit/ApiService,所以工具中得将Retorfit/ApiService单利化了。最重要这种utils太没逼格了。
这里写图片描述

第三步:将Retorif进行二次封装
根据Retrofit的基本使用,主要封装思路:
ApiService对象(单利)
Retrofit对象(单利)
Http请求OkHttpClient对象(单利)
请求参数/接口回调(建造者模式)

1.创建基本Api接口BaseApiService

public interface BaseApiService {
    @GET
    Call<String> get(@Url String url, @QueryMap WeakHashMap<String, Object> params);

    @FormUrlEncoded
    @POST
    Call<String> post(@Url String url, @FieldMap WeakHashMap<String, Object> params);

    @FormUrlEncoded
    @PUT
    Call<String> put(@Url String url, @FieldMap WeakHashMap<String, Object> params);

    @DELETE
    Call<String> delete(@Url String url, @QueryMap WeakHashMap<String, Object> params);
}

2.定义好相关回调接口(访问开始/访问成功/逻辑错误/访问失败/访问结/Callbak)
访问开始

public interface IRequestStart {
    void onRequestStart();
}

访问成功

public interface ISuccess {
    void onSuccess(String response);
}

逻辑错误

public interface IError {
    void onError(int code,String msg);
}

访问失败

public interface IFailure {
    void onFailure();
}

访问结束

public interface IRequestEnd {
    void onRequestEnd();
}

Callbak

public class RequestCallBacks implements Callback<String>{
    private final ISuccess SUCCESS;
    private final IError ERROR;
    private final IFailure FAILURE;
    private final IRequestEnd REQUEST_END;

    public RequestCallBacks(ISuccess success, IError error, IFailure failure, IRequestEnd requestEnd) {
        this.SUCCESS = success;
        this.ERROR = error;
        this.FAILURE = failure;
        this.REQUEST_END = requestEnd;
    }

    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        if (response.isSuccessful()){
            if (call.isExecuted()){
                if (SUCCESS!=null){
                    SUCCESS.onSuccess(response.body());
                }
            }
        }else{
            if (ERROR!=null){
                ERROR.onError(response.code(),response.message());
            }
        }
        if (REQUEST_END!=null){
            REQUEST_END.onRequestEnd();
        }
    }

    @Override
    public void onFailure(Call<String> call, Throwable t) {
       if (FAILURE!=null){
           FAILURE.onFailure();
       }
    }
}

为了确保传进来的参数不被修改,所以定义为final

3.创建一个专门生成Retrofit/ApiService的类ClientCreator

public class ClientCreator {

    /**创建Retorfit*/
    private static final class RetrofitHolder{
        private static final String BASE_URL="https://www.baidu.com/";
        private static final Retrofit RETROFIT=new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(OkHttpClienHolder.OK_HTTP_CLIENT)
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();
    }

    /**创建OkHttpClien对象*/
    private static final class OkHttpClienHolder{
        private static final int TIME_OUT=120;
        private static final OkHttpClient OK_HTTP_CLIENT=new OkHttpClient.Builder()
                .connectTimeout(TIME_OUT, TimeUnit.SECONDS)
                .build();
    }

    /**构建ApiService对象*/
    private static final class ApiServiceHolder{
        private static final BaseApiService API_SERVICE=RetrofitHolder.RETROFIT.create(BaseApiService.class);
    }

    /**获取BaseApiService对象*/
    public static BaseApiService getBaseApiService(){
        return ApiServiceHolder.API_SERVICE;
    }
}

4.定义请求方式HttpMethod
public enum HttpMethod {
GET,
POST,
PUT,
DELETE
}

5.根据构建者模式创建出暴露出来给我们调用的类MyHttpClient/HttpClientBuilder
MyHttpClient中的参数是通过HttpClientBuilder来进行设置

MyHttpClient

public class MyHttpClient {

    private final String URL;
    private final WeakHashMap<String,Object> PARAMS;
    private final IRequestStart REQUEST_START;
    private final ISuccess SUCCESS;
    private final IError ERROR;
    private final IFailure FAILURE;
    private final IRequestEnd REQUEST_END;

     MyHttpClient(String url, WeakHashMap<String,Object> params,IRequestStart requestStart, ISuccess success, IError error, IFailure failure, IRequestEnd requestEnd) {
        this.URL = url;
        PARAMS=params;
        this.REQUEST_START = requestStart;
        this.SUCCESS = success;
        this.ERROR = error;
        this.FAILURE = failure;
        this.REQUEST_END = requestEnd;
    }

    public static HttpClientBuilder builder(){
        return new HttpClientBuilder();
    }


    private RequestCallBacks getRequestCallBacks(){
        return new RequestCallBacks(
                SUCCESS,
                ERROR,
                FAILURE,
                REQUEST_END
        );
    }

    private void requset(HttpMethod method){
        Call<String> call=null;
        BaseApiService apiService=ClientCreator.getBaseApiService();
        if (REQUEST_START!=null){
            REQUEST_START.onRequestStart();
        }
        switch (method){
            case GET:
                call=apiService.get(URL,PARAMS);
                break;
            case POST:
                call=apiService.post(URL,PARAMS);
                break;
            case PUT:
                call=apiService.put(URL,PARAMS);
                break;
            case DELETE:
                call=apiService.delete(URL,PARAMS);
                break;
            default:
                break;
        }
        if (call!=null){
            call.enqueue(getRequestCallBacks());
        }
    }

    public void get(){
        requset(HttpMethod.GET);
    }

    public void post(){
        requset(HttpMethod.POST);
    }

    public void put(){
        requset(HttpMethod.PUT);
    }

    public void delete(){
        requset(HttpMethod.DELETE);
    }

}

HttpClientBuilder

public class HttpClientBuilder {

    private  String mUrl;
    private  final WeakHashMap<String,Object> PARAMS=new WeakHashMap<>();
    private  IRequestStart mRequestStart;
    private  ISuccess mSuccess;
    private  IError mError;
    private  IFailure mFailure;
    private  IRequestEnd mRequestEnd;

    /**
     * 设置接口路径
     * @param url:接口路径
     * */
    public final HttpClientBuilder url(String url){
        this.mUrl=url;
        return this;
    }

    /**
     * 设置请求参数
     * @param key:
     * @param val:
     * */
    public final HttpClientBuilder params(String key,Object val){
        this.PARAMS.put(key,val);
        return this;
    }

    /**
     * 设置请求参数
     * @param params:请求参数
     * */
    public final HttpClientBuilder params(WeakHashMap<String,Object> params){
        this.PARAMS.putAll(params);
        return this;
    }

    /**
     * 设置访问开始接口回调
     * @param requestStart:
     * */
    public final HttpClientBuilder questStart(IRequestStart requestStart){
        this.mRequestStart=requestStart;
        return this;
    }

    /**
     * 设置访问成功接口回调
     * @param success:
     * */
    public final HttpClientBuilder success(ISuccess success){
        this.mSuccess=success;
        return this;
    }

    /**
     * 设置访问错误接口回调
     * @param error:
     * */
    public final HttpClientBuilder error(IError error){
        this.mError=error;
        return this;
    }

    /**
     * 设置访问失败接口回调
     * @param failure:
     * */
    public final HttpClientBuilder failure(IFailure failure){
        this.mFailure=failure;
        return this;
    }

    /**
     * 设置访问结束接口回调
     * @param requestEnd:
     * */
    public final HttpClientBuilder requestEnd(IRequestEnd requestEnd){
        this.mRequestEnd=requestEnd;
        return this;
    }

    /**创建MyHttpClient*/
    public MyHttpClient build(){
        return new MyHttpClient(
                mUrl,
                PARAMS,
                mRequestStart,
                mSuccess,
                mError,
                mFailure,
                mRequestEnd
        );
    }
}

6.Activity调用

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyHttpClient.builder()
                .url("")
                .params("name","张三")
                .questStart(new IRequestStart() {
                    @Override
                    public void onRequestStart() {
                        //loading start
                    }
                })
                .success(new ISuccess() {
                    @Override
                    public void onSuccess(String response) {
                        Toast.makeText(getApplicationContext(),response,Toast.LENGTH_LONG).show();
                    }
                })
                .error(new IError() {
                    @Override
                    public void onError(int code, String msg) {

                    }
                })
                .failure(new IFailure() {
                    @Override
                    public void onFailure() {

                    }
                })
                .requestEnd(new IRequestEnd() {
                    @Override
                    public void onRequestEnd() {
                        // loading hide
                    }
                })
                .build()
                .get();
    }

运行结果:
与上面结果一致。

从调用的结构可以看出这种建造者模式使用起来就像一条链一样,从请求url,参数,接口回调,需要设置哪个就建造对应的数据,使用起来清晰方便。当然,项目开发中,我们往往不会直接返回字符串,所以还可以封装一个泛型,让成功回调返回泛型。

后续….
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值