您好,登錄后才能下訂單哦!
小編給大家分享一下怎么利用Retrofit+RxJava實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求的異常處理,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
通常情況下我們?cè)谂c服務(wù)器進(jìn)行通信的時(shí)候,不一定就不會(huì)出錯(cuò),有時(shí)會(huì)出現(xiàn)其他的錯(cuò)誤,這個(gè)時(shí)候我們只要和服務(wù)器約定好各種異常,在返回結(jié)果處進(jìn)行判斷,到底是執(zhí)行錯(cuò)誤,還是返回正常數(shù)據(jù)。具體的思路大致就是這樣。這里我們定義ExceptionHandle,這里我參考網(wǎng)上的東西,然后稍微做了一些改動(dòng)。
ExceptionHandle
public class ExceptionHandle { private static final int UNAUTHORIZED = 401; private static final int FORBIDDEN = 403; private static final int NOT_FOUND = 404; private static final int REQUEST_TIMEOUT = 408; private static final int INTERNAL_SERVER_ERROR = 500; private static final int BAD_GATEWAY = 502; private static final int SERVICE_UNAVAILABLE = 503; private static final int GATEWAY_TIMEOUT = 504; public static ResponseException handleException(Throwable e){ //轉(zhuǎn)換成ResponseException,根據(jù)狀態(tài)碼判定錯(cuò)誤信息 ResponseException ex; if(e instanceof HttpException){ HttpException httpException=(HttpException)e; /** * 傳入狀態(tài)碼,根據(jù)狀態(tài)碼判定錯(cuò)誤信息 */ ex=new ResponseException(e,ERROR.HTTP_ERROR); switch (httpException.code()){ case UNAUTHORIZED: ex.message="未驗(yàn)證"; break; case FORBIDDEN: ex.message="服務(wù)禁止訪問(wèn)"; break; case NOT_FOUND: ex.message="服務(wù)不存在"; break; case REQUEST_TIMEOUT: ex.message="請(qǐng)求超時(shí)"; break; case GATEWAY_TIMEOUT: ex.message="網(wǎng)關(guān)超時(shí)"; break; case INTERNAL_SERVER_ERROR: ex.message="服務(wù)器內(nèi)部錯(cuò)誤"; break; case BAD_GATEWAY: break; case SERVICE_UNAVAILABLE: break; default: ex.message = "網(wǎng)絡(luò)錯(cuò)誤"; break; } return ex; }else if(e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException){ ex=new ResponseException(e,ERROR.PARSE_ERROR); ex.message="解析錯(cuò)誤"; return ex; }else if(e instanceof ConnectException){ ex=new ResponseException(e,ERROR.NETWORD_ERROR); ex.message="連接失敗"; return ex; }else if(e instanceof javax.net.ssl.SSLHandshakeException){ ex=new ResponseException(e,ERROR.SSL_ERROR); ex.message="證書驗(yàn)證失敗"; return ex; }else { ex=new ResponseException(e,ERROR.UNKNOWN); ex.message="未知錯(cuò)誤"; return ex; } } /** * 約定異常 */ public static class ERROR{ /** * 自定義異常 */ private static final int UNAUTHORIZED = 401;//請(qǐng)求用戶進(jìn)行身份驗(yàn)證 private static final int UNREQUEST=403;//服務(wù)器理解請(qǐng)求客戶端的請(qǐng)求,但是拒絕執(zhí)行此請(qǐng)求 private static final int UNFINDSOURCE=404;//服務(wù)器無(wú)法根據(jù)客戶端的請(qǐng)求找到資源 private static final int SEVERERROR=500;//服務(wù)器內(nèi)部錯(cuò)誤,無(wú)法完成請(qǐng)求。 /** * 協(xié)議出錯(cuò) */ public static final int HTTP_ERROR = 1003; /** * 未知錯(cuò)誤 */ public static final int UNKNOWN = 1000; /** * 解析錯(cuò)誤 */ public static final int PARSE_ERROR = 1001; /** * 網(wǎng)絡(luò)錯(cuò)誤 */ public static final int NETWORD_ERROR = 1002; /** * 證書出錯(cuò) */ public static final int SSL_ERROR = 1005; } /** * 自定義Throwable */ public static class ResponseThrowable extends Exception{ public int code; public String message; public ResponseThrowable(Throwable throwable,int code){ super(throwable); this.code=code; } } /** * 服務(wù)器異常 */ public class ServerException extends RuntimeException{ public int code; public String message; } /** * 統(tǒng)一異常類,便于處理 */ public static class ResponseException extends Exception{ public int code; public String message; public ResponseException (Throwable throwable,int code){ super(throwable); this.code=code; } } }
然后自己定義了一個(gè)Observer
public abstract class BaseObserver<T> implements Observer<T> { private Context context; public BaseObserver(Context context){ this.context=context; } @Override public void onSubscribe(Disposable d) { } @Override public void onNext(T t) { } @Override public void onError(Throwable e) { if(e instanceof ExceptionHandle.ResponseException){ onError((ExceptionHandle.ResponseException)e); }else{ onError(new ExceptionHandle.ResponseException(e,ExceptionHandle.ERROR.UNKNOWN)); } } @Override public void onComplete() { } public abstract void onError(ExceptionHandle.ResponseException exception); }
這里發(fā)生錯(cuò)誤時(shí),Observerble會(huì)先調(diào)用onError(Throwable e),按照我的寫法呢,會(huì)繼續(xù)調(diào)用自定義onError。
那么什么時(shí)候我們對(duì)服務(wù)器的返回結(jié)果進(jìn)行判斷,什么時(shí)候該發(fā)出異常了,請(qǐng)繼續(xù)往下看:
這里我們打算用到ObservableTransformer,Transformer其實(shí)就是就是對(duì)Observable進(jìn)行一定的變換。
先看代碼:
public static class HandleFuc<T> implements Function<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>, T> { @Override public T apply(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response) { if (!Response.getCode().equals("200")){ Throwable e=new Throwable("約定錯(cuò)誤"); /** * 可以根據(jù)不同的狀態(tài)嘛返回不同的提示信息 * 與服務(wù)器約定返回異常信息 */ ExceptionHandle.ResponseException responseException = new ExceptionHandle.ResponseException(e, ExceptionHandle.ERROR.HTTP_ERROR); return (T) Observable.error(responseException);//發(fā)出錯(cuò)誤異常 } return (T) Observable.just(Response);//發(fā)出服務(wù)器數(shù)據(jù),返回Observable<Response> } } //處理錯(cuò)誤的變換 public static class ErrorTransformer<T> implements ObservableTransformer { @Override public Observable<T> apply(Observable upstream) { return (Observable<T>) upstream.flatMap(new HandleFuc<T>());//flatMap會(huì)重新創(chuàng)建一個(gè)Observable,當(dāng)它處理完事件后會(huì)匯入原先的Observable對(duì)象。 } }
說(shuō)明:我們的HandleFuc其實(shí)就是對(duì)服務(wù)器返回來(lái)的結(jié)果進(jìn)行判斷,邏輯很簡(jiǎn)單了,錯(cuò)誤就拋出異常直接執(zhí)行error方法。如果沒有錯(cuò)誤,就發(fā)送正常數(shù)據(jù)。這里值的說(shuō)明一點(diǎn)的是,flatMap會(huì)重新創(chuàng)建一個(gè)Observable,當(dāng)它處理完事件后會(huì)重新匯入初始的Observerble并開始發(fā)送事件。
使用起來(lái)其實(shí)就很簡(jiǎn)單了:
@Provides ErrorTransformer provideErrorTransformer(){ return new ErrorTransformer(); } public Observable<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>> getApplication(PageParmForm pageParmForm){ return retrofit.create(Service.class) .getApplicationList(pageParmForm) .compose(errorTransformer) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); }
直接用compose方法包裹起來(lái)即可。
最后看看Activity:
new NetRepository().getApplication(new PageParmForm(Constant.orderStr,Constant.pageNum,Constant.pageSize)) .subscribe(new BaseObserver<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>>(NetWorkActivity.this) { @Override public void onError(ExceptionHandle.ResponseException exception) { myToast.showToast(NetWorkActivity.this,exception.getMessage()); Log.d("carhandbook",exception.getMessage()); } @Override public void onNext(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response) { data=Response.getData().getList(); code=Response.getCode(); myToast.showToast(NetWorkActivity.this,code); generateAdapter.setData(data); generateAdapter.notifyDataSetChanged(); } });
以上是“怎么利用Retrofit+RxJava實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求的異常處理”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。