Retrofit简单封装(打印日志,缓存数据)

照着网上的例子敲了一遍,感觉糊里糊涂的,就写下来加深一下印象
由于例子中要用的Retrofit请求,json解析,Rxjava,运行时请求权限,故需要加入以下依赖
另外感谢张鸿洋老师提供的开放API

//Retrofit,它依赖于Okhttp,所以同时会下载Okhttp的依赖
implementation 'com.squareup.retrofit2:retrofit:2.5.0'

//Retrofit解析json,依赖于Gson,所以会下载Gson的依赖
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'//ConverterFactory的Gson依赖包 用于将请求结果转换为实体类型

implementation 'com.squareup.retrofit2:converter-scalars:2.5.0'//ConverterFactory的String依赖包 用于将请求结果转换为基本类型,一般为String

//retrofit支持rxjava
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'

//rxjava和rxAndroid
implementation 'io.reactivex.rxjava2:rxjava:2.2.7'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'

//第三方日志拦截器
implementation('com.github.ihsanbal:LoggingInterceptor:3.0.0') {
        exclude group: 'org.json', module: 'json'
}

//万能适配器
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'

 //权限工具
implementation 'com.yanzhenjie.permission:support:2.0.1'

关于Retrofit的使用这里就不做过多介绍,封装之后的Retrofit客户端如下,功能在Okhttp客户端实现

 public static <T> T createApi(Class<T> clazz,String baseUrl){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(getOkhttpClient())
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//否则会报错java.lang.IllegalArgumentException: Unable to create call adapter for io.reactivex.Observable
                .build();
        return retrofit.create(clazz);
    }

Okhttp客户端代码如下

 private static OkHttpClient getOkhttpClient(){
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)//日志
                .addNetworkInterceptor(cacheInterceptor)//缓存拦截器
                .addInterceptor(cacheInterceptor)
                .cache(HttpCache.getCache())//开启缓存
                .build();
        return client;
    }

日志拦截器(第三方)

public class LoggingInterceptor {

   public static com.ihsanbal.logging.LoggingInterceptor interceptor = new com.ihsanbal.logging.LoggingInterceptor.Builder()
            .loggable(BuildConfig.DEBUG)
            .setLevel(Level.BASIC)
            .log(Platform.INFO)
            .request("request")
            .response("response")
            .build();

}

设置缓存目录

public class HttpCache {
    private static final int HTTP_RESPONSE_DISK_CACHE_MAX_SIZE = 50 * 1024 * 1024;

    public static Cache getCache(){
        File file = new File(getDiskCacheDir());
        Cache cache = new Cache(file, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE);
        return cache;//通过Okhttp的cache()方法会自动把数据缓存到定义的缓存目录
    }

    /**
     * 获取缓存地址,应用卸载后,缓存也会清除
     * @return
     */
    private static String getDiskCacheDir(){
        String cachePath = null;
        //如果有外部存储且外部存储卡是内置的(不是SD card)
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || Environment.isExternalStorageRemovable()){
            cachePath = AppUtil.getContext().getExternalCacheDir().getAbsolutePath();
        }else {
            cachePath = AppUtil.getContext().getCacheDir().getAbsolutePath();
        }
        return cachePath;
    }
}

缓存拦截器

public class CacheInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        int maxAge = 60 * 60;//有网络时设置缓存超时时间为1个小时
        int maxStale = 60 * 60 * 24 * 28; //无网络时缓存4周
        Request request = chain.request();
        if (NetworkConnectionUtil.isNetworkConnected(AppUtil.getContext())){
            request = request.newBuilder()
                    .cacheControl(CacheControl.FORCE_NETWORK)
                    .build();//有网络是只从网络取数据
            Response response = chain.proceed(request);
            return response.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Cache-Control")
                    .header("Cache-Control", "public, max-age="+ maxAge)
                    .build();
        }else {
            request = request.newBuilder()
                    .cacheControl(CacheControl.FORCE_CACHE)//没有网络是强制从缓存中请求数据
                    .build();
            Response response = chain.proceed(request);
            return response.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }

    }
}

接下来是结合rxjava简单的使用

观察者的简单封装

public class BaseObserver<T> implements Observer<T> {
    private ObserverOnNextListener listener;
    private Context context;
    private Disposable d;

    public BaseObserver(ObserverOnNextListener listener, Context context) {
        this.listener = listener;
        this.context = context;
    }

    @Override
    public void onSubscribe(Disposable d) {
        this.d = d;
    }

    @Override
    public void onNext(T t) {
        listener.onNext(t);
    }

    @Override
    public void onError(Throwable e) {
        d.dispose();
    }

    @Override
    public void onComplete() {
        d.dispose();
    }

    public interface ObserverOnNextListener<T>{
        void onNext(T t);
    }
}

订阅关系的封装

public class ApiMethods {

    /**
     * 封装线程管理和订阅的过程
     * @param observable 被观察者
     * @param observer 观察者
     */
    public static void ApiSubscribe(Observable observable, Observer observer){
            observable.subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())//????
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(observer);
    }

    /**
     * 获取列表
     * @param observer
     */
    public static void getHomeArticles(Observer<Article> observer){
        ApiSubscribe(RetrofitCreateHelper.getWanApi().getHomeArticles(),observer);
    }
}

activity中的使用

BaseObserver.ObserverOnNextListener listener = new BaseObserver.ObserverOnNextListener<Article>() {

            @Override
            public void onNext(Article article) {
                List<Article.DataBean.DatasBean> datas = article.getData().getDatas();
                initData(datas);
            }
        };

ApiMethods.getHomeArticles(new BaseObserver<Article>(listener,this));

本文参考了Android 优雅的让RxJava2.0+Retrofit2.0结合使用

项目代码:github

发布了62 篇原创文章 · 获赞 45 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/parade0393/article/details/88358670
今日推荐