Retrofit+RxJava优雅的处理服务器返回异常错误Word文档下载推荐.docx
- 文档编号:6842614
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:19
- 大小:34.81KB
Retrofit+RxJava优雅的处理服务器返回异常错误Word文档下载推荐.docx
《Retrofit+RxJava优雅的处理服务器返回异常错误Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Retrofit+RxJava优雅的处理服务器返回异常错误Word文档下载推荐.docx(19页珍藏版)》请在冰点文库上搜索。
Response<
User>
>
(){
@Override
publicvoidonCompleted(){
}
publicvoidonError(Throwablee){
publicvoidonNext(Response<
data){
if(data.state==1001){
//.....
}elseif(data.state==1002){
});
现在我希望在发生任何错误的情况下,都会调用onError事件,并且由model来处理错误信息。
那么,此时我们就应该有一个ExceptionEngine来处理事件流中的错误信息了。
在工作流中处理异常
在正常情况下,我们获取网络数据的流程通常如下:
请求接口->
解析数据->
更新UI
整个数据请求过程都是发生在Rx中的工作流之中。
当有异常产生的时候,我们要尽量不在ui层里面进行判断,换句话说,我们没有必要去告诉ui层具体的错误信息,只需要让他弹出一个信息(Toast或者Dialog)展示我们给它的信息就行。
请求接口和数据解析都可能出错,所以在这两层进行错误处理。
为了更好的解耦,我们通过拦截器拦截错误,然后根据错误类型分发信息。
拦截器
数据解析层的拦截器
这个拦截器主要是为了获取具体的错误信息,分发给上层的UI,给用户以提示,增强用户体验。
publicObservable<
Weather>
getWeather(StringcityName){
returnweatherService.getWeather(cityName)
//拦截服务器返回的错误
.map(newServerResponseFunc<
())
//HttpResultFunc()为拦截onError事件的拦截器,后面会讲到,这里先忽略
.onErrorResumeNext(newHttpResponseFunc<
());
//拦截固定格式的公共数据类型Response<
判断里面的状态码
privateclassServerResponseFunc<
implementsFunc1<
T>
publicTcall(Response<
reponse){
//对返回码进行判断,如果不是0,则证明服务器端返回错误信息了,便根据跟服务器约定好的错误码去解析异常
if(reponse.state!
=0){
//如果服务器端有错误信息返回,那么抛出异常,让下面的方法去捕获异常做统一处理
thrownewServerException(reponse.state,reponse.message);
//服务器请求数据成功,返回里面的数据实体
returnreponse.data;
所以整个逻辑是这样的:
所以在前三步的过程中,只要发生异常(服务器返回的错误也抛出了)都会抛出,这时候就触发了RxJava的OnError事件。
处理onError事件的拦截器
这个拦截器主要是将异常信息转化为用户”能看懂”的友好提示。
privateclassHttpResponseFunc<
Throwable,Observable<
publicObservable<
call(Throwablethrowable){
//ExceptionEngine为处理异常的驱动器
returnObservable.error(ExceptionEngine.handleException(throwable));
两个拦截器以前使用,代码如下:
//HttpResponseFunc()为拦截onError事件的拦截器
调用:
APIWrapper.getInstance().getWeather("
北京"
.subscribe(newSampleProgressObserver<
(MainActivity.this){
publicvoidonNext(WeatherBeanweatherBean){
tv.setText(weatherBean.toString());
相关类:
publicclassRxSubscriber<
extendsErrorSubscriber<
publicvoidonStart(){
super.onStart();
DialogHelper.showProgressDlg(context,"
正在加载数据"
);
DialogHelper.stopProgressDlg();
protectedvoidonError(ApiExceptionex){
Toast.makeText(context,ex.message,Toast.LENGTH_SHORT).show();
publicvoidonNext(Tt){
publicabstractclassErrorSubscriber<
extendsObserver<
if(einstanceofApiException){
onError((ApiException)e);
}else{
onError(newApiException(e,123));
/**
*错误回调
protectedabstractvoidonError(ApiExceptionex);
处理异常的驱动器
package;
import.ParseException;
importcom.google.gson.JsonParseException;
importorg.json.JSONException;
import.ConnectException;
importretrofit2.adapter.rxjava.HttpException;
*CreatedbyLzxon2016/7/11.
publicclassExceptionEngine{
//对应HTTP的状态码
privatestaticfinalintUNAUTHORIZED=401;
privatestaticfinalintFORBIDDEN=403;
privatestaticfinalintNOT_FOUND=404;
privatestaticfinalintREQUEST_TIMEOUT=408;
privatestaticfinalintINTERNAL_SERVER_ERROR=500;
privatestaticfinalintBAD_GATEWAY=502;
privatestaticfinalintSERVICE_UNAVAILABLE=503;
privatestaticfinalintGATEWAY_TIMEOUT=504;
publicstaticApiExceptionhandleException(Throwablee){
ApiExceptionex;
if(einstanceofHttpException){//HTTP错误
HttpExceptionhttpException=(HttpException)e;
ex=newApiException(e,ERROR.HTTP_ERROR);
switch(httpException.code()){
caseUNAUTHORIZED:
caseFORBIDDEN:
caseNOT_FOUND:
caseREQUEST_TIMEOUT:
caseGATEWAY_TIMEOUT:
caseINTERNAL_SERVER_ERROR:
caseBAD_GATEWAY:
caseSERVICE_UNAVAILABLE:
default:
ex.message="
网络错误"
;
//均视为网络错误
break;
returnex;
}elseif(einstanceofServerException){//服务器返回的错误
ServerExceptionresultException=(ServerException)e;
ex=newApiException(resultException,resultException.code);
ex.message=resultException.message;
}elseif(einstanceofJsonParseException
||einstanceofJSONException
||einstanceofParseException){
ex=newApiException(e,ERROR.PARSE_ERROR);
解析错误"
//均视为解析错误
}elseif(einstanceofConnectException){
ex=newApiException(e,ERROR.NETWORD_ERROR);
连接失败"
}else{
ex=newApiException(e,ERROR.UNKNOWN);
未知错误"
//未知错误
*约定异常
publicclassERROR{
*未知错误
publicstaticfinalintUNKNOWN=1000;
*解析错误
publicstaticfinalintPARSE_ERROR=1001;
*网络错误
publicstaticfinalintNETWORD_ERROR=1002;
*协议出错
publicstaticfinalintHTTP_ERROR=1003;
publicclassApiExceptionextendsException{
publicintcode;
publicApiException(Throwablethrowable,intcode){
super(throwable);
this.code=code;
publicclassServerExceptionextendsRuntimeException{
DialogHelper.Java
publicclassDialogHelper{
*通用Dialog
*
//因为本类不是activity所以通过继承接口的方法获取到点击的事件
publicinterfaceOnOkClickListener{
abstractvoidonOkClick();
*Listener
publicinterfaceOnCancelClickListener{
abstractvoidonCancelClick();
privatestaticAlertDialogmDialog;
publicstaticvoidshowDialog(Contextcontext,Stringtitle,Stringcontent,finalOnOkClickListenerlistenerYes,
finalOnCancelClickListenerlistenerNo){
showDialog(context,context.getString(android.R.string.ok),context.getString(android.R.string.cancel),title,content,listenerYes,listenerNo);
publicstaticvoidshowDialog(Contextcontext,Stringok,Stringcancel,Stringtitle,Stringcontent,finalOnOkClickListenerlistenerYes,
AlertDialog.Builderbuilder=newAlertDialog.Builder(context);
builder.setMessage(content);
//设置title
builder.setTitle(title);
//设置确定按钮,固定用法声明一个按钮用这个setPositiveButton
builder.setPositiveButton(ok,
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intwhich){
//如果确定被电击
if(listenerYes!
=null){
listenerYes.onOkClick();
mDialog=null;
//设置取消按钮,固定用法声明第二个按钮要用setNegativeButton
builder.setNegativeButton(cancel,
//如果取消被点击
if(listenerNo!
listenerNo.onCancelClick();
//控制这个dialog可不可以按返回键,true为可以,false为不可以
builder.setCancelable(false);
//显示dialog
mDialog=builder.create();
if(!
mDialog.isShowing())
mDialog.show();
publicstaticvoidshowDialog(Contextcontext,intok,intcancel,inttitle,intcontent,finalOnOkClickListenerlistenerYes,
showDialog(context,context.getString(ok),context.getString(cancel),context.getString(title),context.getString(content),listenerYes,listenerNo);
staticProgressDialogprogressDlg=null;
*启动进度条
*@paramstrMessage进度条显示的信息
*@param//当前的activity
publicstaticvoidshowProgressDlg(Contextctx,StringstrMessage){
if(null==progressDlg){
if(ctx==null)return;
progressDlg=newProgressDialog(ctx);
//设置进度条样式
progressDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//提示的消息
progressDlg.setMessage(strMessage);
progressDlg.setIndeterminate(false);
progressDlg.setCancelable(true);
progressDlg.show();
publicstaticvoidshowProgressDlg(Contextctx){
showProgressDlg(ctx,"
"
*结束进度条
publicstaticvoidstopProgressDlg(){
if(null!
=progressDlg&
&
progressDlg.isShowing()){
progressDlg.dismiss();
progressDlg=null;
=dialog&
dialog.isShowing()){
dialog.dismiss();
dialog=null;
privatestaticDialogdialog;
publicstaticvoidshowDialogForLoading(Contextcontext,Stringmsg,booleancancelable){
if(null==dialog){
if(null==context)return;
Viewview=LayoutInflater.from(context).inflate(R.layout.layout_loading_dialog,null);
TextViewloadingText=(TextView)view.findViewById(R.id.loading_tip_text);
loadingText.setText(msg);
dialog=newDialog(context,R.style.loading_dialog_style);
dialog.setCancelable(cancelable);
dialog.setCanceledOnTouchOutside(cancelable);
dialog.setContentView(iew,newLinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
Activityactivity=(Activity)context;
if(activity.isFinishing())return;
dialog.show();
可能本博客也不是最好的解决方案,如果有更好的想法,我愿与你互相交流!
分享:
Retrofit+RxJava错误预处理
看到bobo_wang的文章,不仅感觉有受益匪浅,这里做下介绍。
首先定义如下Transformer转换器。
publicstatic<
Observable.Transformer<
sTransformer(){
returnresponseObservable->
responseObservable.map(tResponse->
tResponse.success)thrownewRuntimeExceptio
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Retrofit RxJava 优雅 处理 服务器 返回 异常 错误