onError(ThrowableHandler.handleThrowable(throwable));
} else {
onError(new HttpThrowable(HttpThrowable.UNKNOWN, “未知错误”, throwable));
}
}
//应用中具体实现的是下面这个onError方法
public void onError(HttpThrowable httpThrowable) {
Toast.makeText(AppGlobals.getApplication().getApplicationContext(),
httpThrowable.message, Toast.LENGTH_LONG).show();
}
}
- 请求后台访问数据的接口类
/**
- 请求后台访问数据的接口类
*/
public interface ServiceApi {
/**
- Get方法 @Query
*/
@GET(“home/paintingList”)
Observable<Result> getSearchContent(@Query(“searchContent”) String text, @Query(“size”) int size);
/**
- Get方法 @Query
*/
@GET(“home/paintingList”)
Observable<Result> getSearchContent2(@Query(“searchContent”) String text, @Query(“size”) int size);
@POST(“applets/code2Session”)
Observable<Result> postCode2Session(@Body Map<String, Object> code);
}
- BaseActivity中绑定生命周期
public abstract class BaseActivity extends AppCompatActivity {
/**
- 绑定生命周期
*/
protected LifecycleProvider<Lifecycle.Event> rxLifecycle = AndroidLifecycle.createLifecycleProvider(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
- 调用
package cc.network.rxjava;
import android.content.Intent;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.ArrayMap;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import androidx.lifecycle.Lifecycle;
import com.alibaba.fastjson.JSON;
import com.yumakeji.rxjava.network.RetrofitClient;
import com.yumakeji.rxjava.network.bean.Result;
import com.yumakeji.rxjava.network.callback.ConsumerCallback;
import com.yumakeji.rxjava.network.callback.ObserverCallback;
import com.yumakeji.rxjava.network.callback.ThrowableCallback;
import com.yumakeji.rxjava.network.error.HttpThrowable;
import com.yumakeji.rxjava.network.handler.RetryWithDelay;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import cc.network.rxjava.rxjava.ServiceApi;
import cc.network.rxjava.textbean.LoginBean;
import cc.network.rxjava.textbean.Top250Bean;
import cc.network.rxjava.viewmodel.RxjavaViewModel;
import cn.yumakeji.jetpackroomstudy.R;
import cn.yumakeji.lib_common.global.AppGlobals;
import cn.yumakeji.lib_common.utils.AppUtils;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Action;
import io.reactivex.rxjava3.functions.BiFunction;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
/**
-
防止多次点击
-
https://www.jianshu.com/p/ea45670a364f,
-
-
Retrofit
-
https://blog.csdn.net/huangxiaoguo1/article/details/65627293
-
-
Rxjava
-
https://www.jianshu.com/p/092452f287db
-
不继承RxAppCompatActivity的情况下使用RxLifeCycle
-
https://blog.csdn.net/kevinscsdn/article/details/78980010
*/
public class RxjavaActivity extends BaseActivity {
private ListView mListView;
private List strings = new CopyOnWriteArrayList<>();
private final String TAG = “Rxjava”;
private RxjavaViewModel viewModel;
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
getLifecycle().removeObserver(viewModel);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rxjava);
mListView = findViewById(R.id.list_item);
strings.add("Get方法 @Query ");
strings.add("Post方法 @Body ");
strings.add(“使用Rxjava切换线程”);
strings.add(“Rxjava(一)emitter”);
strings.add(“Rxjava(二)变换操作符Map”);
strings.add(“Rxjava(三)FlatMap”);
strings.add(“Rxjava(四)concatMap”);
strings.add(“Rxjava(五)接口顺序调用”);
strings.add(“Rxjava(六)接口顺序调用(内部发生错误)”);
strings.add(“Rxjava(七)Zip来打包”);
}
/**
-
去体验Retrofit
-
@param view
*/
public void onRetrofitClick(View view) {
startActivity(new Intent(this, RetrofitActivity.class));
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
viewModel = new RxjavaViewModel(this);
getLifecycle().addObserver(viewModel);
mListView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, strings));
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0://Get方法 @Query
RetrofitClient.getInstance()
.create(ServiceApi.class)// 创建服务
.getSearchContent("", 5)//调用接口
.subscribeOn(Schedulers.io())// 指定被观察者的操作在io线程中完成
.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))
.observeOn(AndroidSchedulers.mainThread())//指定观察者接收到数据,然后在Main线程中完成
.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
.doAfterTerminate(() -> viewModel.hintProgressDialog())
.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))//生命周期
.subscribe(new ConsumerCallback() {
@Override
public void onSucceed(Top250Bean result) {
// 成功获取数据
Toast.makeText(AppGlobals.getApplication().getApplicationContext(),
“成功了” + result, Toast.LENGTH_LONG).show();
}
@Override
public void onError(int code, String msg) {
// 获取数据失败
Toast.makeText(AppGlobals.getApplication().getApplicationContext(),
msg, Toast.LENGTH_LONG).show();
}
}, new ThrowableCallback() {
@Override
public void onError(HttpThrowable httpThrowable) {
// 获取数据失败
Log.i(TAG, httpThrowable.message);
}
});
break;
case 1://POST方法 @Body
ArrayMap<String, Object> map = new ArrayMap<>();
map.put(“jsCode”, “033sHaaK03pRwa2Bic9K0EmcaK0sHaaq”);
RetrofitClient.getInstance()
.create(ServiceApi.class)
.postCode2Session(map)
.subscribeOn(Schedulers.io())
.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))
.observeOn(AndroidSchedulers.mainThread())
.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))
.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
.doAfterTerminate(() -> viewModel.hintProgressDialog())
.subscribe(new ObserverCallback() {
@Override
public void onSucceed(LoginBean result) {
// 成功获取数据
Toast.makeText(AppGlobals.getApplication().getApplicationContext(),
“成功了” + result, Toast.LENGTH_LONG).show();
}
@Override
public void onFail(int code, String msg) {
// 获取数据失败
Toast.makeText(AppGlobals.getApplication().getApplicationContext(),
msg, Toast.LENGTH_LONG).show();
}
@Override
public void onComplete() {
super.onComplete();
}
});
break;
case 2://使用Rxjava切换线程
Observable.empty().observeOn(Schedulers.io())
.doOnComplete(new Action() {
@Override
public void run() throws Throwable {
Log.i(TAG, “我是子线程:” + AppUtils.isMainThread());
Observable.timer(3, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> msgManagement(10))
.subscribe();
Observable.empty().observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> msgManagement(20)
).subscribe();
}
}).subscribe();
break;
case 3:
//Rxjava(一)emitter 发射器
/**
-
借鉴:给初学者的RxJava2.0教程(一)
-
https://www.jianshu.com/p/464fa025229e
-
规则:
-
1、上游可以发送无限个onNext, 下游也可以接收无限个onNext.
-
2、当上游发送了一个onComplete后, 上游onComplete之后的事件将会继续发送, 而下游收到onComplete事件之后将不再继续接收事件.
-
3、当上游发送了一个onError后, 上游onError之后的事件将继续发送, 而下游收到onError事件之后将不再继续接收事件.
-
4、上游可以不发送onComplete或onError.
-
5、最为关键的是onComplete和onError必须唯一并且互斥, 即不能发多个onComplete, 也不能发多个onError,
-
也不能先发一个onComplete, 然后再发一个onError, 反之亦然
-
注: 关于onComplete和onError唯一并且互斥这一点, 是需要自行在代码中进行控制, 如果你的代码逻辑中违背了这个规则,
-
**并不一定会导致程序崩溃. ** 比如发送多个onComplete是可以正常运行的, 依然是收到第一个onComplete就不再接收了,
-
但若是发送多个onError, 则收到第二个onError事件会导致程序会崩溃.
*/
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {
Log.e(TAG, “是否是主线程=>” + AppUtils.isMainThread());
emitter.onNext(“huangxiaoguo1”);
emitter.onNext(“huangxiaoguo2”);
emitter.onNext(“huangxiaoguo3”);
emitter.onComplete();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
private Disposable mDisposable;
/**
-
不带任何参数的subscribe() 表示下游不关心任何事件,你上游尽管发你的数据去吧, 老子可不管你发什么.
-
带有一个Consumer参数的方法表示下游只关心onNext事件, 其他的事件我假装没看见,
-
@param d
*/
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d(TAG, “subscribe”);
mDisposable = d;
}
@Override
public void onNext(@NonNull String s) {
/**
-
当调用它的dispose()方法时, 它就会将两根管道切断, 从而导致下游收不到事件.
-
调用dispose()并不会导致上游不再继续发送事件, 上游会继续发送剩余的事件
*/
Log.e(TAG, “onNext 是否是主线程 ==>” + AppUtils.isMainThread());
Log.d(TAG, “onNext==>” + s);
if (s.equals(“huangxiaoguo2”)) {
mDisposable.dispose();
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.d(TAG, “onError”);
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete ");
}
});
break;
case 4:
//Rxjava(二)变换操作符Map
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {
Log.e(TAG, “subscribe 是否是主线程 ==>” + AppUtils.isMainThread());
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
})
.subscribeOn(Schedulers.io())
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Throwable {
Log.e(TAG, “map 是否是主线程 ==>” + AppUtils.isMainThread());
return “我是在map中处理过了的===>” + String.valueOf(integer);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, “accept 是否是主线程 ==>” + AppUtils.isMainThread());
Log.i(TAG, “accept===>” + s);
}
});
break;
case 5:
//flatMap 并不保证事件的顺序
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).flatMap(new Function<Integer, ObservableSource>() {
@Override
public ObservableSource apply(Integer integer) throws Throwable {
ArrayList strings = new ArrayList<>();
for (int i = 0; i < 3; i++) {
strings.add("I am value " + integer);
}
return Observable.fromIterable(strings).delay(2, TimeUnit.SECONDS);
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Throwable {
Log.d(TAG, s);
}
});
break;
case 6:
//concatMap 保证顺序
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).concatMap(new Function<Integer, ObservableSource>() {
@Override
public ObservableSource apply(Integer integer) throws Throwable {
ArrayList strings = new ArrayList<>();
for (int i = 0; i < 3; i++) {
strings.add("I am value " + integer);
}
return Observable.fromIterable(strings).delay(2, TimeUnit.SECONDS);
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Throwable {
Log.d(TAG, s);
}
});
break;
case 7:
//Rxjava(五)接口顺序调用
RetrofitClient.getInstance()
.create(ServiceApi.class)// 创建服务
.getSearchContent("", 5)//调用接口
.subscribeOn(Schedulers.io())// 指定被观察者的操作在io线程中完成
.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))
.observeOn(AndroidSchedulers.mainThread())//指定观察者接收到数据,然后在Main线程中完成
.doOnNext(new ConsumerCallback() {
@Override
public void onSucceed(Top250Bean result) {
Log.e(TAG, result.toString());
}
@Override
public void onError(int code, String msg) {
}
})
.observeOn(Schedulers.io())
.flatMap(new Function<Result, Observable<Result>>() {
@Override
public Observable<Result> apply(Result result) throws Throwable {
Log.e(TAG, result.getMessage());
ArrayMap<String, Object> map = new ArrayMap<>();
map.put(“jsCode”, “033sHaaK03pRwa2Bic9K0EmcaK0sHaaq”);
return RetrofitClient.getInstance().create(ServiceApi.class).postCode2Session(map);
}
})
.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))//生命周期
.observeOn(AndroidSchedulers.mainThread())
.doAfterTerminate(() -> viewModel.hintProgressDialog())
.subscribe(new ConsumerCallback() {
@Override
public void onSucceed(LoginBean result) {
Log.e(TAG, result.toString());
}
@Override
public void onError(int code, String msg) {
Log.e(TAG, msg);
}
}, new ThrowableCallback() {
@Override
public void onError(HttpThrowable httpThrowable) {
super.onError(httpThrowable);
}
});
break;
case 8:
//Rxjava(六)接口顺序调用(内部发生错误)
ArrayMap<String, Object> map1 = new ArrayMap<>();
map1.put(“jsCode”, “033sHaaK03pRwa2Bic9K0EmcaK0sHaaq”);
RetrofitClient.getInstance()
.create(ServiceApi.class)// 创建服务
.postCode2Session(map1)//调用接口
.subscribeOn(Schedulers.io())// 指定被观察者的操作在io线程中完成
.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))
.observeOn(AndroidSchedulers.mainThread())//指定观察者接收到数据,然后在Main线程中完成
.doOnNext(new ConsumerCallback() {
@Override
public void onSucceed(LoginBean result) {
Log.e(TAG, result.toString());
}
@Override
public void onError(int code, String msg) {
Log.e(TAG, msg);
}
})
.observeOn(Schedulers.io())
.flatMap(new Function<Result, Observable<Result>>() {
@Override
public Observable<Result> apply(Result result) throws Throwable {
if (!result.isOk()) {
return null;
}
return RetrofitClient.getInstance().create(ServiceApi.class).getSearchContent("", 5);
}
})
.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试的间隔,第二个参数为重试几次
.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))//生命周期
.observeOn(AndroidSchedulers.mainThread())
.doAfterTerminate(() -> viewModel.hintProgressDialog())
.subscribe(new ConsumerCallback() {
@Override
public void onSucceed(Top250Bean result) {
Log.e(TAG, result.toString());
}
@Override
public void onError(int code, String msg) {
Log.e(TAG, msg);
}
}, new ThrowableCallback() {
@Override
public void onError(HttpThrowable httpThrowable) {
super.onError(httpThrowable);
}
});
break;
case 9:
//Rxjava(七)Zip来打包请求
Observable.zip(RetrofitClient.getInstance()
.create(ServiceApi.class)
.getSearchContent("", 1)
.subscribeOn(Schedulers.io()),
RetrofitClient.getInstance()
.create(ServiceApi.class)
.getSearchContent2("", 1)
.subscribeOn(Schedulers.io()),
new BiFunction<Result, Result, Top250Bean>() {
@Override
public Top250Bean apply(Result result, Result result2) throws Throwable {
Top250Bean data1 = JSON.parseObject(JSON.toJSONString(result.data), Top250Bean.class);
Top250Bean data2 = JSON.parseObject(JSON.toJSONString(result.data), Top250Bean.class);
data1.getRecords().addAll(data2.getRecords());
return data1;
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Top250Bean result) throws Throwable {
Log.e(TAG, result.toString());
Log.e(TAG, result.getRecords().size()+"—");
}
});
break;
}
}
});
}
/**
-
代替Handler
-
@param what
*/
private void msgManagement(int what) {
if (what == 10) {
Log.i(TAG, “我是代替Handler 有延时” + AppUtils.isMainThread());
} else {
Log.i(TAG, “我是代替Handler 没有延时” + AppUtils.isMainThread());
}
}
}
- MVVM中管理Rxjava的生命周期
//使用rxlife对viewModel生命周期执行支持(rxlifecycle在google jetpack的videModel中不太好用,针对的是MVP)
api ‘com.ljx.rxlife3:rxlife-rxjava:3.0.0’
注意: 一定要在Activity/Fragment通过以下方式获取ViewModel对象,否则RxLife接收不到生命周期的回调
viewModel = new ViewModelProvider(this).get(RxjavaViewModel.class);
Observable.interval(2, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.to(RxLife.to(this))
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Throwable {
Log.e(“huangxiaoguo”, “接口轮询”);
}
});
其他设计到的类
- error
package com.yumakeji.rxjava.network.error;
public class HttpThrowable extends Exception {
public int errorType;
public String message;
public Throwable throwable;
/**
- 未知错误
*/
public static final int UNKNOWN = 1000;
/**
- 解析错误
*/
public static final int PARSE_ERROR = 1001;
/**
- 连接错误
*/
public static final int CONNECT_ERROR = 1002;
/**
- DNS解析失败(无网络)
*/
public static final int NO_NET_ERROR = 1003;
/**
- 连接超时错误
*/
public static final int TIME_OUT_ERROR = 1004;
/**
- 网络(协议)错误
*/
public static final int HTTP_ERROR = 1005;
/**
- 证书错误
*/
public static final int SSL_ERROR = 1006;
public HttpThrowable(int errorType, String message, Throwable throwable) {
super(throwable);
this.errorType = errorType;
this.message = message;
this.throwable = throwable;
}
}
import com.alibaba.fastjson.JSONException;
import com.google.gson.JsonParseException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import retrofit2.HttpException;
public class ThrowableHandler {
public static HttpThrowable handleThrowable(Throwable throwable) {
if (throwable instanceof HttpException) {
return new HttpThrowable(HttpThrowable.HTTP_ERROR, “网络(协议)异常”, throwable);
} else if (throwable instanceof JsonParseException || throwable instanceof JSONException || throwable instanceof ParseException) {
return new HttpThrowable(HttpThrowable.PARSE_ERROR, “数据解析异常”, throwable);
} else if (throwable instanceof UnknownHostException) {
return new HttpThrowable(HttpThrowable.NO_NET_ERROR, “网络连接失败,请稍后重试”, throwable);
} else if (throwable instanceof SocketTimeoutException) {
return new HttpThrowable(HttpThrowable.TIME_OUT_ERROR, “连接超时”, throwable);
} else if (throwable instanceof ConnectException) {
return new HttpThrowable(HttpThrowable.CONNECT_ERROR, “连接异常”, throwable);
} else if (throwable instanceof javax.net.ssl.SSLHandshakeException) {
return new HttpThrowable(HttpThrowable.SSL_ERROR, “证书验证失败”, throwable);
} else {
return new HttpThrowable(HttpThrowable.UNKNOWN, throwable.getMessage(), throwable);
}
}
}
- 误时重试
public class RetryWithDelay implements Function<Observable, ObservableSource<?>> {
private int retryDelaySeconds;//延迟重试的时间
private int retryCount;//记录当前重试次数
private int retryCountMax;//最大重试次数
public RetryWithDelay(int retryDelaySeconds, int retryCountMax) {
this.retryDelaySeconds = retryDelaySeconds;
this.retryCountMax = retryCountMax;
}
@Override
public ObservableSource<?> apply(Observable throwableObservable) throws Exception {
//方案一:使用全局变量来控制重试次数,重试3次后不再重试,通过代码显式回调onError结束请求
return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Throwable throwable) throws Exception {
//如果失败的原因是UnknownHostException(DNS解析失败,当前无网络),则没必要重试,直接回调error结束请求即可
if (throwable instanceof UnknownHostException) {
return Observable.error(throwable);
}
//没超过最大重试次数的话则进行重试
if (++retryCount <= retryCountMax) {
//延迟retryDelaySeconds后开始重试
return Observable.timer(retryDelaySeconds, TimeUnit.SECONDS);
}
return Observable.error(throwable);
}
});
}
}
- 拦截器
public class CacheIntercepter implements Interceptor {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
//对request的设置用来指定有网/无网下所走的方式
//对response的设置用来指定有网/无网下的缓存时长
Request request = chain.request();
if (!NetworkUtils.isNetWorkAvailable(AppGlobals.getApplication())) {
//无网络下强制使用缓存,无论缓存是否过期,此时该请求实际上不会被发送出去。
//有网络时则根据缓存时长来决定是否发出请求
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE).build();
}
Response response = chain.proceed(request);
if (NetworkUtils.isNetWorkAvailable(AppGlobals.getApplication())) {
//有网络情况下,超过1分钟,则重新请求,否则直接使用缓存数据
int maxAge = 60; //缓存一分钟
String cacheControl = “public,max-age=” + maxAge;
//当然如果你想在有网络的情况下都直接走网络,那么只需要
//将其超时时间maxAge设为0即可
return response.newBuilder()
.header(“Cache-Control”, cacheControl)
.removeHeader(“Pragma”).build();
} else {
//无网络时直接取缓存数据,该缓存数据保存3天
int maxStale = 60 * 60 * 24 * 3; //无网络时,设置超时为3天
return response.newBuilder()
.header(“Cache-Control”, “public,only-if-cached,max-stale=” + maxStale)
.removeHeader(“Pragma”).build();
}
}
}
public class HeaderInterceptor implements Interceptor {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder();
s, TimeUnit.SECONDS);
}
return Observable.error(throwable);
}
});
}
}
- 拦截器
public class CacheIntercepter implements Interceptor {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
//对request的设置用来指定有网/无网下所走的方式
//对response的设置用来指定有网/无网下的缓存时长
Request request = chain.request();
if (!NetworkUtils.isNetWorkAvailable(AppGlobals.getApplication())) {
//无网络下强制使用缓存,无论缓存是否过期,此时该请求实际上不会被发送出去。
//有网络时则根据缓存时长来决定是否发出请求
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE).build();
}
Response response = chain.proceed(request);
if (NetworkUtils.isNetWorkAvailable(AppGlobals.getApplication())) {
//有网络情况下,超过1分钟,则重新请求,否则直接使用缓存数据
int maxAge = 60; //缓存一分钟
String cacheControl = “public,max-age=” + maxAge;
//当然如果你想在有网络的情况下都直接走网络,那么只需要
//将其超时时间maxAge设为0即可
return response.newBuilder()
.header(“Cache-Control”, cacheControl)
.removeHeader(“Pragma”).build();
} else {
//无网络时直接取缓存数据,该缓存数据保存3天
int maxStale = 60 * 60 * 24 * 3; //无网络时,设置超时为3天
return response.newBuilder()
.header(“Cache-Control”, “public,only-if-cached,max-stale=” + maxStale)
.removeHeader(“Pragma”).build();
}
}
}
public class HeaderInterceptor implements Interceptor {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder();