网络请求模块设计 | 青训营笔记

69 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第5天

前言

在刚学习安卓1个月后,我第一次接触到了OkHttp,当时因为还是新手,所以没有接触到Retrofit,直到我开始学习架构知识时,才知道还有一个基于OkHttp的Retrofit,这让我瞬间感觉到在项目里进行网络请求是如此的方便,不需要自己封装OkHttp,免去了大部分繁琐的步骤,通过注解和几句简单的代码即可完成网络请求,这直接把我从直接使用OkHttp的苦海中拉了出来。但是在一段时间后,我开始思考,既然我在使用Okhttp时会通过封装来让使用Okhttp来进行请求时更方便,更好管理,我在使用Retrofit时为什么不这么做呢?所以我开始对Retrofit进行封装————

正文

1.管理与快速创建

封装网络请求库的原因之一就是为了方便管理创建出来的对象,而不同对象的区别最大就在于其对应的url不同,所以可以通过Map<String,Retrofit>来对Retrofit来进行管理,其键值为对应的url,有了思路之后,就可以创建一个管理类来进行封装管理,首先创建RetrofitManager并写一个可以获取RetrofitManager实例的方法

//获取实例
public static RetrofitManager getInstance() {
    if (instance == null) {
        synchronized (RetrofitManager.class) {
            if (instance == null) {
                instance = new RetrofitManager();
            }
        }
    }
    return instance;
}

然后通过Map来对Retrofit按不同url进行管理,再写一个从Map中获取Retrofit对象的方法,这时候就需要注意了,因为Retrofit是需要创建以后放到Map中才能通过url取出来,去从Map中使用url去获取Retrofit时,如果这个url下没创建过Retrofit则会返回null,所以我们还需要再其返回值未null时创建一个Retrofit对象进行返回,这样也可以免去我们在使用Retrofit时频繁创建相同的对象的情况。这里我为了能够使用GSON来自动对返回值进行解析,所以增加了一个GsonConverterFactory。上代码:

//获取对应url的Retrofit对象
public Retrofit getRetrofit(String url){
    //判断url是否为空
    if (TextUtils.isEmpty(url)){
        throw new NullPointerException("url is null");
    }
    //获取Retrofit对象并返回
    Retrofit retrofit = retrofitMap.get(url);
    if (retrofit == null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        retrofitMap.put(url, retrofit);
    }
    return retrofit;
}

这样,一个简单的不能再简单的封装和管理就完成了,我的类里还有其它的功能就不在这展示出来了,下面赶紧讲下怎么使用:

//获取Retrofit
retrofit = RetrofitManager.getInstance().getRetrofit(Constant.DOUYIN_OPENAPI);
apiService = retrofit.create(ApiService.class);
Call<UserInfo> userInfo = apiService.getUserInfo(userToken,userToken,userOpenId);
RetrofitUtil.enqueue(userInfo, new ResponseCallback<>() {
    @Override
    public void onSuccess(UserInfo userInfo) {
        if (userInfo.getData().getErrorCode() == 0) {
            ...
        }
    }

    @Override
    public void onFailure(Throwable t) {
            ...
    }
});

可以看到,获取一个Retrofit对象变得十分的方便,而且还不会重复创建对象或者,代码可以说是简洁了不少,后面那个RetrofitUtil是请求封装,我在里面封装了Call不同的请求方式(同步、异步),当然还包括了一些请求回调时候的统一操作,因为只是对Call的Respose进行了一些预操作和直接使用call.enqueue没多大区别,这里就不展示Retrofit的代码了,当然,RetrofitUtil的存在也是很有必要的,毕竟封装一些重复的操作也可以少写很多代码,保持代码的整洁

心得

因为我学习安卓没有系统的教学,大部分知识都是自己通过查资料和看官方文档来获取的,因此对Retrofit的封装的技巧很多都是学习了网上的博客,再根据自己的理解来进行封装,这篇笔记也是记录这一次的学习过程,如果之后学习到了更好的封装技巧,我也会继续更新这篇文章