Android Rxjava+retrofit Network exception capture, state code unified processing
Preface
Recently using Rxjava+retrofit for development, in the project encountered such a requirement, when the networking request to obtain data anomalies, the corresponding message and statuscode need to be obtained and displayed, such as:
1. Server connection error: The corresponding return 404,500 and so on;
2. No network status (no 4g,3g, no wifi environment or inferior);
Reference articles:
Rxjava +retrofit you need to master a few tips, retrofit cache, Rxjava encapsulation, unified pair have no network processing, exception handling, return the result problem @ Code small white one, simple to obtain processing
The simplest way to deal with the throwable is to handle the type judgment directly:
First judge the network environment if (! NETUTILS.IS4G (context)) {return;}//re-networking request, judge the Throwable servicehelper.getinstance (). Getmodelresult (param1 , param2). Subscribeon (Schedulers.io ()). Observeon (Androidschedulers.mainthread ()). Subscrib
E (New subscriber<model> () {@Override public void oncompleted () { @Override public void OnError (Throwable e) {if (e Instanc) EOF HttpException) {//Get corresponding statuscode and message HttpException exception =
(HttpException) E;
String message = Exception.response (). message ();
int code = exception.response (). code (); }else if (e instanceof sslhandshakeexception) {//Next is the various exception type judgments ...} else if (e instanceof ...)
{
}...
... @Override public void OnNext (model model) {} });
Obviously, the code is not difficult to understand, but very cumbersome, always do not have to do such a large chunk of code copy and paste it every time.
Please note that the httpexception of type judgment is
Import retrofit2.adapter.rxjava.HttpException;
So we need to rely on:
Compile ' com.squareup.retrofit2:adapter-rxjava:2.1.0 '
Second, neterrorutil packaging
1. First, we create a Throwable management class
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 responethrowable HandleException (Throwable e) {responethrowable ex;
LOG.I ("tag", "e.tostring =" + e.tostring ());
if (e instanceof httpexception) {HttpException HttpException = (httpexception) e; ex = new Responethrowable (E, ERROR.
HTTP_ERROR); Switch (Httpexception.code ()) {case Unauthorized:case forbidden:case NO T_found:case request_timeout:case gateway_timeout:case INTERNAL_server_error:case bad_gateway:case Service_unavailable:default:
Ex.code = Httpexception.code ();
ex.message = "Network error";
Break
return ex;
else if (e instanceof serverexception) {serverexception resultexception = (serverexception) e;
ex = new Responethrowable (resultexception, Resultexception.code);
Ex.message = Resultexception.message;
return ex; else if (e instanceof jsonparseexception | | e instanceof jsonexception/*| | e instanceof parseexception*/) {ex = new responethrowable (E, ERROR.
PARSE_ERROR);
Ex.message = "Parse error";
return ex;
else if (e instanceof connectexception) {ex = new responethrowable (e, error.netword_error);
Ex.message = "Connection Failed";
return ex; else if (e instanceof javax.net.ssl.SSLHandshakeException) {ex = new responethrowable (e, ERROR.)
SSL_ERROR);
Ex.message = "Certificate validation failed";
return ex; else {ex = new responethrowable (E, ERROR.
UNKNOWN);
Ex.message = "Unknown error";
return ex; }/** * Convention exception/Class Error {/** * Unknown error */public static FINA
l int UNKNOWN = 1000;
/** * Parse Error * * public static final int parse_error = 1001;
/** * Network error */public static final int netword_error = 1002;
/** * protocol Error * * public static final int http_error = 1003;
/** * Certificate Error * * public static final int ssl_error = 1005;
public static class Responethrowable extends Exception {public int code;
public String message; Public responethrowable (Throwable throwable, INT code) {super (throwable);
This.code = code; After the/** * serverexception occurs, it is automatically converted to responethrowable return */class Serverexception extends Runtimeexcep
tion {int code;
String message; }
}
In this class, we make the throwable of the same type:
1. If we are exception, we will judge again, according to different kinds of exception, converted to responethrowable return, and give different code and message;
2. If runtimeexception, we convert to responethrowable return; in summary, we take the exception that we get, The HandleException () method is transformed into a unified responethrowable return, which contains the code and message. 2. Then create a new subscriber base class
/** * Subscriber base class, where you can handle the client network connection status * (for example, no wifi, no 4g, no networking, etc.) * Created by FCN-MQ on 2017/4/19.
* * Public abstract class Mysubscriber<t> extends subscriber<t> {private context;
Public Mysubscriber {this.context = context;
@Override public void OnStart () {Super.onstart ();
LOG.I ("tag", "Mysubscriber.onstart ()"); Next you can check the network connection and other operations if (! Networkutil.isnetworkavailable (context) {toast.maketext, "current network is not available, check network condition", Toast.length_short). Sho
W ();
Be sure to take the initiative to call the following sentence, cancel this Subscriber subscription if (!isunsubscribed ()) {unsubscribe ();
} return; @Override public void OnError (Throwable e) {log.e ("tag", "mysubscriber.throwable =" +e.tostring ())
;
LOG.E ("tag", "mysubscriber.throwable =" +e.getmessage ()); if (e instanceof Exception) {//Access gets the corresponding Exception OnerroR (Exceptionhandle.handleexception (e)); }else {//Throwable and unknown error status code returned to OnError (new exceptionhandle.responethrowable e,exception
Handle.ERROR.UNKNOWN));
} public abstract void OnError (exceptionhandle.responethrowable responethrowable);
@Override public void oncompleted () {log.i ("tag", "Mysubscriber.oncomplete ()"); }
}
This is understandable, we can unify the judgment of the client network environment in the base class, or when the network anomaly occurs, the unified conversion to
Responethrowable, in OnError ( Exceptionhandle.responethrowable responethrowable), the abstract callback method needs to be implemented by ourselves. 3. Using in code:
New Retrofit.builder (). BaseURL (Constantsapi.base_douban). Addconverterfactory (Gsonconverterfacto
Ry.create ()). Addcalladapterfactory (Rxjavacalladapterfactory.create ()). Client (client) . Build (). Create (Doubanmovieservice.class)//Get the corresponding service object. Getmodelresult (param1, param2) Network request. Subscribeon (Schedulers.io ()). Observeon (Androidschedulers.mainthread ()). Su Bscribe (new mysubscriber<model> (context) {@Override public void OnNext (Model mode
L) {...} @Override public void OnError (exceptionhandle.responethrowable throwable) {logutil.
M ("tag", "Throwable =" + throwable.tostring ());
Then you can handle it according to the status code ... int statusCode = Throwable.code;
Switch (statusCode) { Case ExceptionHandle.ERROR.SSL_ERROR:break;
Case ExceptionHandle.ERROR.UNKNOWN:break;
Case ExceptionHandle.ERROR.PARSE_ERROR:break;
Case ExceptionHandle.ERROR.NETWORD_ERROR:break;
Case ExceptionHandle.ERROR.HTTP_ERROR:break; }
}
});
Finally is the Neterrorutil source address: dot I dot I
"GitHub Address" https://github.com/ButQingMei/Samples.git