本文已經(jīng)廢棄。請(qǐng)讀者移步到
Android使用rxjava封裝重試處理工具類 - 簡(jiǎn)書
我們?cè)谧鲆恍┊惒秸?qǐng)求時(shí),為了確保請(qǐng)求成功需要進(jìn)行重試。
那么我們需要靈活的配置重試間隔時(shí)間,重試次數(shù), 還需要寫個(gè)倒計(jì)時(shí)代碼。
為此,本文使用rxjava為基礎(chǔ)封裝了一個(gè)工具類。
其中要注意的是內(nèi)存泄漏問(wèn)題,為此使用rxjava的周期組件AndroidLifecycleScopeProvider進(jìn)行處理,如果非全局上下文需要在構(gòu)造方法傳入LifecycleOwner類。
下面直接上代碼:
public class RetryForTimeDownHelper {
private static final String TAG = "RetryForTimeDownHelper";
/**
* 重試次數(shù)
*/
private volatile int retryCount;
/**
* 最大重試次數(shù)
*/
private int maxRetryCount;
/**
* 重試時(shí)間
*/
private long retryTimeMilli;
private OnRetryCallBack onRetryCallBack;
private WeakReference<LifecycleOwner> lifecycleOwnerWeakReference;
/**
* @param lifecycleOwner 非全局上下文需要傳入,防止內(nèi)存泄漏
* @param maxRetryCount 最多重試次數(shù)
* @param retryTimeMilli 重試間隔時(shí)間 單位毫秒
* @param onRetryCallBack 重試回調(diào):重試、重試結(jié)束處理結(jié)果
*/
public RetryForTimeDownHelper(LifecycleOwner lifecycleOwner, int maxRetryCount, long retryTimeMilli, OnRetryCallBack onRetryCallBack) {
if (lifecycleOwner != null) {
this.lifecycleOwnerWeakReference = new WeakReference<>(lifecycleOwner);
}
this.maxRetryCount = maxRetryCount;
this.retryTimeMilli = retryTimeMilli;
this.onRetryCallBack = onRetryCallBack;
}
public RetryForTimeDownHelper(int maxRetryCount, long retryTimeMilli, OnRetryCallBack onRetryCallBack) {
this(null, maxRetryCount, retryTimeMilli, onRetryCallBack);
}
public int getRetryCount() {
return retryCount;
}
public void retry(FailBean failBean) {
retryCount++;
if (retryCount > maxRetryCount) {
if (onRetryCallBack != null) {
onRetryCallBack.onComplete(failBean);
}
return;
}
//非全局上下文需要傳入,防止內(nèi)存泄漏
if (lifecycleOwnerWeakReference != null) {
LifecycleOwner lifecycleOwner = lifecycleOwnerWeakReference.get();
if (lifecycleOwner != null) {
timeDownRetryLifecycle(lifecycleOwner);
}
return;
}
//全局上下文中
timeDownRetry();
}
private void timeDownRetry() {
//倒計(jì)時(shí)3秒 重試
Observable.timer(retryTimeMilli, TimeUnit.MILLISECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(@NonNull Disposable disposable) {
}
@Override
public void onNext(@NonNull Long number) {
if (onRetryCallBack != null) {
onRetryCallBack.onNext();
}
}
@Override
public void onError(@NonNull Throwable throwable) {
if (throwable != null) {
Log.e(TAG, "onError: ", throwable);
}
}
@Override
public void onComplete() {
}
});
}
private void timeDownRetryLifecycle(LifecycleOwner lifecycleOwner) {
//倒計(jì)時(shí)3秒 重試
Observable.timer(retryTimeMilli, TimeUnit.MILLISECONDS)
//AutoDispose 防止內(nèi)存泄漏
.as(AutoDispose.<Long>autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(@NonNull Disposable disposable) {
}
@Override
public void onNext(@NonNull Long number) {
if (onRetryCallBack != null) {
onRetryCallBack.onNext();
}
}
@Override
public void onError(@NonNull Throwable throwable) {
if (throwable != null) {
Log.e(TAG, "onError: ", throwable);
}
}
@Override
public void onComplete() {
}
});
}
public interface OnRetryCallBack {
/**
* 調(diào)用重試
*/
void onNext();
/**
* 處理結(jié)果
*/
void onComplete(FailBean failBean);
}
public static class FailBean {
private String errorCodeStr;
private String errorMsgStr;
public String getErrorCodeStr() {
return errorCodeStr;
}
public void setErrorCodeStr(String errorCodeStr) {
this.errorCodeStr = errorCodeStr;
}
public String getErrorMsgStr() {
return errorMsgStr;
}
public void setErrorMsgStr(String errorMsgStr) {
this.errorMsgStr = errorMsgStr;
}
}
}
使用步驟
我們以登錄為例
1、在調(diào)用登錄時(shí)構(gòu)造對(duì)象
private volatile RetryForTimeDownHelper retryForTimeDownHelper;
public void login(){
//重試3次,間隔3秒重試
retryForTimeDownHelper = new RetryForTimeDownHelper(3, 3 * 1000, new RetryForTimeDownHelper.OnRetryCallBack() {
@Override
public void onNext() {
//重試登錄
reLogin();
}
@Override
public void onComplete() {
//處理登錄失敗結(jié)果
setFail();
}
});
//登錄的實(shí)現(xiàn)方法
reLogin();
}
其中回調(diào)方法onNext()是進(jìn)行重試的方法,onComplete()處理重試失敗結(jié)果
2、在登錄失敗時(shí)調(diào)用下重試
public void reLogin() {
LoginHelper.getInstance().login(userId, token, new LoginCallBack(){
@Override
public void onFailed (String errorCode){
if (retryForTimeDownHelper != null) {
RetryForTimeDownHelper.FailBean failBean = new RetryForTimeDownHelper.FailBean();
failBean.setErrorCodeStr(errorCode);
retryForTimeDownHelper.retry(failBean);
}
}
@Override
public void onSuccess () {
retryForTimeDownHelper = null;
}
}
}