Retrofit简单封装(打印日志,缓存数据)
照着网上的例子敲了一遍,感觉糊里糊涂的,就写下来加深一下印象由于例子中要用的Retrofit请求,json解析,Rxjava,运行时请求权限,故需要加入以下依赖另外感谢张鸿洋老师提供的开放API//Retrofit,它依赖于Okhttp,所以同时会下载Okhttp的依赖implementation 'com.squareup.retrofit2:retrofit:2.5.0'//Ret...
·
照着网上的例子敲了一遍,感觉糊里糊涂的,就写下来加深一下印象
由于例子中要用的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
更多推荐
已为社区贡献1条内容
所有评论(0)