第一次写博客,写的不好请各位看官见谅,如有错误,欢迎批评指正~
简介:RxJava和Retrofit可谓目前Android最火的两大框架了。本文只对两者的使用做一个简单的实例,侧重于两者结合对网络请求的封装,各自高深的用法和源码还请各位看官度娘之~。
一:基础篇
implementation "com.squareup.okhttp3:logging-interceptor:3.9.0"
implementation "com.squareup.retrofit2:retrofit:2.3.0"
implementation "com.squareup.retrofit2:converter-gson:2.3.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
implementation "io.reactivex.rxjava2:rxjava:2.0.6"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.4.0'
implementation "com.trello.rxlifecycle2:rxlifecycle:2.2.1"
implementation "com.trello.rxlifecycle2:rxlifecycle-components:2.2.1"
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
无奈去了github官网看了下,找了几个demo。地址如下:https://github.com/ReactiveX/RxJava。
根据几个demo总结下来,基本可以得出以下几点:
RxJava是基于观察者和被观察者模式,观察者和被观察者之间存在一种订阅的关系,观察者可以知道被观察者某种事件下所发生的一切。何谓某种事件下呢?举个例子:你老婆拿着你的工资卡去商场购物,买了一个两万块钱的包包,这时候你就可以收到银行发来的一条消费两万元的短信,然后暗骂一句败家娘们。这个时候你就是观察者,你老婆就是被观察者。但你不可能观察你老婆所有的事情吧,比如问了个路、喝了杯咖啡等等,这些你老婆不告诉你你是不会知道的,你能知道的仅仅是你老婆花了两万块钱买了个很贵的包而已。凡是你卡里余额变动,你都能知道,我们可以说这是基于银行卡余额变动事件下的观察者模式。总结四个字:基于事件。
RxJava它是异步的。这个比较好理解,就好像我去蛋糕店买蛋糕,我跟老板说了我想要什么样的蛋糕,然后我告诉老板我什么时候来取,不必一直在蛋糕店里等着,我可以去忙其它的事,这就是异步。
被观察者是可以通过某种操作符转变的,好像很难理解啊。还是上面那个例子:你老婆回到家,你当面骂了你老婆一句你个败家娘们,然后你老婆把你打了一顿。你可能会说,我老婆打我跟这个有毛线关系啊。好吧,让我们来分析一下:本来你在心里暗骂,你老婆听不见,也不会打你,可你非得作死的操作了一波(当面骂她),你就是通过当面骂这个操作成功激怒你老婆,变身母老虎,把你揍了一顿。老婆->母老虎。这就是转变。RxJava中也内置了许多操作符,可以把被观察者进行转变,转变为另外一种形态,咱们下面再说。
说了半天,RxJava到底怎么用呢?
来,让我们一二三三步走。
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
//把这个消息发送出去。
emitter.onNext("我花了两万块钱买了个包");
}
});
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String msg) {
//你收到买包的消息。
Log.e("RxJava--------------",msg);
//你暗骂的话。
Log.e("RxJava--------------","收到了,败家娘们");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
//订阅。
observable.subscribe(observer);
ok,让我们来看下结果。
当然这些代码也可以连起来写,RxJava支持链式调用,就像下面这样:
Observable.create((ObservableOnSubscribe<String>) emitter -> {
//通知你买了个两万块钱的包。
emitter.onNext("我花了两万块钱买了个包");
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String msg) {
//你收到买包的消息。
Log.e("RxJava--------------", msg);
//你暗骂的话。
Log.e("RxJava--------------", "收到了,败家娘们");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
好了,说完最基本的使用,咱们再来说说转化,此处只举一个例子,RxJava有很多操作符,分别可以实现不同的功能,这里只介绍一种,map操作符。让各位看官有个印象。如果感兴趣,可移步RxJava操作符,还是刚刚上面的代码,稍微加一点。
Observable.create((ObservableOnSubscribe<String>) emitter -> {
//通知你买了个两万块钱的包。
emitter.onNext("我花了两万块钱买了个包");
}).map(new Function<String, String>() {
@Override
public String apply(String s) throws Exception {
//map操作符变换了下,在原来的字符串上加了 "哈哈哈哈哈哈哈哈哈哈哈哈"。
return s + "哈哈哈哈哈哈哈哈哈哈哈哈";
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String msg) {
//你收到买包的消息。因为通过map转化过,所以收到的消息,是之前的消息+新增的字符串
Log.e("RxJava--------------", msg);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
结果如下:
map操作符中传入一个Function对象,需要分别传入两个泛型,第一个泛型是你最开始的被观察者的泛型,后面一个泛型是你通过map操作符转换之后想要变成的被观察者的泛型。我这里是字符串转字符串,只是加了一点点信息而已,可以转化成任意类型,比如转化成一个对象,怎么弄呢?
Observable.create((ObservableOnSubscribe<String>) emitter -> {
//通知你买了个两万块钱的包。
emitter.onNext("我花了两万块钱买了个包");
}).map(new Function<String, MyBean>() {
@Override
public String apply(String s) throws Exception {
//将字符串封装成一个对象
MyBean bean = new MyBean();
bean.setWords(s);
return bean;
}
}).subscribe(new Observer<MyBean >() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(MyBean bean) {
//你收到买包的消息。因为通过map转化成了MyBean对象,所以这里可以直接取到转换后的值。
Log.e("RxJava--------------", bean.getWords());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
MyBean代码:
而且被观察者也可以通过多种操作符转化多次。因为重点不在这里,RxJava的基本使用到此为止,感兴趣的可以看一看这一篇博客Rxjava2具体使用
Retrofit retrofit = new Retrofit.Builder()
//设置baseUrl,baseUrl+接口中配置的地址组成真正的请求地址。
.baseUrl("http://wanandroid.com/")
.client(new OkHttpClient())
.build();
package project.hx.com.rxjava;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;
public interface WanAndroidService {
/**
* 获取公众号列表
* @Call
*/
@GET("wxarticle/chapters/json")
//baseUrl+接口中配置的地址组成真正的请求地址。
Call<ResponseBody> getPublicAccountList();
}
WanAndroidService service = retrofit.create(WanAndroidService.class);
Call<ResponseBody> responseBodyCall = service.getPublicAccountList();
responseBodyCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e("玩Android数据-------",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
下面看下格式化后的数据:
{
"data": [{
"children": [],
"courseId": 13,
"id": 408,
"name": "鸿洋",
"order": 190000,
"parentChapterId": 407,
"userControlSetTop": false,
"visible": 1
}, {
"children": [],
"courseId": 13,
"id": 421,
"name": "互联网侦察",
"order": 190010,
"parentChapterId": 407,
"userControlSetTop": false,
"visible": 1
}],
"errorCode": 0,
"errorMsg": ""
}
然而
别急啊大兄弟,这只是Retrofit单独的使用方法,如果要配合RxJava该怎么用呢?很简单。在初始化Retrofit的时候,加两行代码,如下:
Retrofit retrofit = new Retrofit.Builder()
//设置baseUrl,baseUrl+接口中配置的地址组成真正的请求地址。
.baseUrl("http://wanandroid.com/")
.client(new OkHttpClient())
.addConverterFactory(GsonConverterFactory.create()) // 支持Gson解析
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava2
.build();
至于请求接口的代码也要稍微改动一下,像下面这样:
public interface WanAndroidService {
/**
* 获取公众号列表
* @return Observable
*/
@GET("wxarticle/chapters/json")
Observable<PublicAccountBean> getPublicAccountList();
}
GsonConverterFactory的作用是将请求的结果转化成具体的JavaBean。至于Observable,是不是很熟悉?对,它就是RxJava中的被观察者,RxJava2CallAdapterFactory是将该javaBean的对象再封装成Observable,中间经历了两次转化。让我们看下最终的调用:
WanAndroidService service = retrofit.create(WanAndroidService.class);
service.getPublicAccountList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<PublicAccountBean>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(PublicAccountBean publicAccountBean) {
//请求成功
for (int i = 0; i < publicAccountBean.getData().size(); i++) {
Log.e("data----------", publicAccountBean.getData().get(i).getName());
}
}
@Override
public void onError(Throwable e) {
//失败
}
@Override
public void onComplete() {
}
});
来看下最终的数据:
这样就实现了RxJava和Retrifit的搭配使用,同样RxJava是异步的,所以我们可以在onNext方法中再去执行请求成功之后的操作。这里RxJava直接把转化成javaBean和Observable都给你做了,你拿到最终的对象用就完事儿了,还能调用RxJava的api,各种转换各种浪,如果这样还不能吸引你的话。。。
好了,以上就是RxJava和Retrofit的基本使用,还有个RxLifecycle。它的作用主要是用来解决RxJava引起的内存泄漏。RxJava发布一个订阅后,页面finish时,如果没有取消订阅,或导致Activity或者Frament无法回收,从而导致内存泄漏。解决办法可以在onDestroy为每个观察者取消订阅。但万一有很多呢,有可能会有遗漏,我们可以在使用RxJava时就对观察者进行绑定,一旦Activity或Frament进入某个生命周期,让该观察者取消订阅。举个例子?
Observable.interval(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//在Activity onDestroy时解除订阅,防止内存泄漏。
.compose(RxLifecycle.bindUntilEvent(BehaviorSubject.create(), ActivityEvent.DESTROY))
.subscribe();
就一句代码的事,基础篇完事儿了。擦,基础篇竟然写了这么多。。。。。
二. 封装篇
走你~
至于mvp在此处就不在赘述了,网上也有许多博客。在传统的mvc模式中,Activity往往既充当表现层,又充当逻辑管理层。当逻辑和界面交互逻辑过于复杂的时候,Activity中的代码就会很臃肿,不便于维护。而mvp是将Activity只当做ui表现层,逻辑处理的代码剥离开来,放在一个新的类中,我们称之为Presenter,是MVP中的P层。Activity持有该类的对象,同时该类也能调用Activity中的代码,这样便将逻辑代码和ui交互代码分开,便于开发和维护。好了,话不多说,下面进入正题。
public class RetrofitManager {
private Retrofit mRetrofit;
private static class InstanceHelper {
static RetrofitManager instance = new RetrofitManager();
}
public static RetrofitManager getInstance() {
return InstanceHelper.instance;
}
private RetrofitManager() {
mRetrofit = new Retrofit.Builder()
//设置baseUrl
.baseUrl("http://wanandroid.com/")
//设置OkHttpClient对象
.client(createOkhttpClient())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
.addConverterFactory(GsonConverterFactory.create()) // 支持Gson解析
.addConverterFactory(ScalarsConverterFactory.create())//支持字符串
.build();
}
/*
* 创建OkHttpClient对象。Retrofit底层基于OkHttpClient进行网络请求。
* */
private OkHttpClient createOkhttpClient() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
return new OkHttpClient.Builder()
//设置连接超时时间
.connectTimeout(30, TimeUnit.SECONDS)
//设置读取超时时间
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
//添加日志过滤器
.addInterceptor(httpLoggingInterceptor)
//添加BaseInterceptor拦截器
.addInterceptor(new BaseInterceptor())
.build();
}
public <T> T createApi(final Class<T> service) {
return mRetrofit.create(service);
}
}
这里在顺带说下OkHttp自带的拦截器功能。所谓拦截器,就是对发出的请求和返回的响应都可以进行拦截,并进行相应的处理,再把请求发送出去或者把响应返回给用户。比如有些时候,我们需要在每个请求中都添加一些公共参数,每次请求再去添加这些参数也可以,但是这样不太优雅,这时我们就可以为OkHttpClient配置一个拦截器,拦截每一个请求,并在请求中加上我们的公共参数,这样客户端发出的每一个请求都会带上公共参数;或者有时候需要在请求头中添加某些信息,比如机型、系统型号等等信息,每个请求都手动加也不太好,同样可以在拦截器中进行配置,把公共的头部信息加进去,然后再发送给服务端。至于具体的实现,OkHttp中内置了一个接口Interceptor,自定 义拦截器需要实现该接口,并重写其intercept方法。然后再配置到OkHttpClient中
即可。代码就一行:
主要是BaseInterceptor的实现。代码如下:
public class BaseInterceptor implements Interceptor {
@NonNull
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//POST请求
if (request.method().equals("POST")) {
FormBody formBody = null;
FormBody.Builder bodyBuilder = new FormBody.Builder();
if (request.body() instanceof FormBody) {
formBody = (FormBody) request.body();
//把原来的参数添加到新的构造器,(因为没找到直接添加,所以就new新的)
for (int i = 0; i < formBody.size(); i++) {
bodyBuilder.add(formBody.name(i), formBody.value(i));
}
//添加公共参数
formBody = bodyBuilder
.add("pubParam1", "1")
.add("pubParam2", "2")
.add("pubParam3", "3")
.build();
//添加请求头
request = request
.newBuilder()
.post(formBody)
.addHeader("Content-Type", "application/json;charset=UTF-8")
.addHeader("User-Agent", "android")
.build();
}
return chain.proceed(request);
} else {
//添加公共参数
HttpUrl.Builder urlBuilder = request.url()
.newBuilder()
.addQueryParameter("pubParam1", "1")
.addQueryParameter("pubParam2", "2")
.addQueryParameter("pubParam3", "3");
//添加请求头
Request.Builder newBuilder = request.newBuilder()
.method(request.method(), request.body())
.url(urlBuilder.build())
.addHeader("Content-Type", "application/json;charset=UTF-8")
.addHeader("User-Agent", "android");
return chain.proceed(newBuilder.build());
}
}
}
这里分了POST和GET等其它请求,POST和GET添加请求头和添加参数的代码不同,所以得判断请求的method。好吧 ,让我们来看下GET请求,通过Fiddler抓包工具抓到的请求:
公共参数拼接在url地址后面,请求头中放了两个字段Content-Type和User-Agent,和我们设置的值是一致的。再看下POST请求的结果,代码需要做稍许的修改
请求一次再看抓包的结果
POST请求和GET不同,公共参数在请求体中,请求头不变。同样也生效了。好吧,拦截器还有许多可以深挖的东西,网上也有许多很好的博客,各位看官想深入了解可以自行百度哈~
public interface BaseView{
/**
* Show loading
*/
void showLoading();
/**
* Hide loading
*/
void hideLoading();
/**
* Show Msg
*/
void showMsg(String msg);
/**
* 获取Lifecycle对象,用于Activity onDestroy时取消观察者的订阅。
*/
<R> BehaviorSubject<R> getLifeCycleSubject();
}
public abstract class BasePresenter<V extends BaseView> {
protected V mView;
public BasePresenter(V mView) {
this.mView = mView;
}
}
public abstract class BaseActivity<T extends BasePresenter> extends RxAppCompatActivity implements BaseView {
//RxLifecycle对象,每个Activity 调用onDestroy时用来取消观察者的订阅。
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
//Presanter,继承自BasePresenter。
protected T mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//构建该Activity的Presenter对象。
mPresenter = createPresenter();
}
public abstract T createPresenter();
@SuppressWarnings("unchecked")
@Override
public final BehaviorSubject getLifeCycleSubject() {
return lifecycleSubject;
}
}
代码应该挺好理解,主要就是Activity和Prensenter的相互调用,这两个分别充当mvp中的V和P。我们在BaseActivity的基础上写一个Demo Activity,再来解释要好一点。我们都知道mvp好是好,但是有一个问题就是会让整个项目的类变的很多。每写一个Activity都要一个Prensenter(继承自BasePrensenter)和一个View接口(继承自BaseView)。即每次都要额外写两个类 ,写多了也挺烦,然而又不能省略,所以这里把Presenter和View放到一个类中。我们称之为Contract类,至于为啥叫这个名字,我也是参考了别人的命名哈哈~
public class MainContract {
/*
* Activity实现的接口
* */
public interface IView extends BaseView {
void doSomething();
}
public static class Prensenter extends BasePresenter<IView> {
private API api;
private Gson gson;
public Prensenter(IView mView) {
super(mView);
api = RetrofitManager.getInstance().createApi(API.class);
gson = new Gson();
}
public void getPublicAccountList() {
api.getPublicAccountList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bindUntilEvent(mView.getLifeCycleSubject(), ActivityEvent.DESTROY))
.doOnSubscribe(disposable -> mView.showLoading())
.doFinally(() -> mView.hideLoading())
.subscribe(new Observer<PublicAccountBean>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(PublicAccountBean publicAccountBean) {
//成功
mView.doSomething();
for (int i = 0; i < publicAccountBean.getData().size(); i++) {
Log.e("data----------", publicAccountBean.getData().get(i).getName());
}
}
@Override
public void onError(Throwable e) {
//失败
Log.e("error--------",e.getMessage());
}
@Override
public void onComplete() {
}
});
}
}
}
可以看到我们把View和Presenter放在了一个类中。Presenter中初始化了Api请求接口,请求的时候直接调用Api请求接口中的方法就行啦。返回一个Observable对象,然后直接用就行了。好吧我们再看一下Activity中的代码:
public class MainActivity extends BaseActivity<MainContract.Prensenter> implements MainContract.IView {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPresenter.getPublicAccountList();
}
@Override
public MainContract.Prensenter createPresenter() {
return new MainContract.Prensenter(this);
}
@Override
public void showLoading() {
}
@Override
public void hideLoading() {
}
@Override
public void showMsg(String msg) {
}
@Override
public void doSomething() {
}
}
结果是一样的,这里就不贴图片了哈,可以看到Actvity实现了MainContract中的IView接口,而Presenter中又持有一个IView接口的变量,所以Presenter可以调用MainActivity中的代码,同样Activity也持有一个Presenter的变量,所以Activity可以和Presenter相互调用。好吧,我实在不知道怎么描述了,只可意会不可言传~
写到这,基本的框架已经搭建起来了,BaseActivity里面可以根据自己的需求抽取一些公共的方法。但还有一个点可以稍微优化下:
api.getPublicAccountList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bindUntilEvent(mView.getLifeCycleSubject(), ActivityEvent.DESTROY))
.doOnSubscribe(disposable -> mView.showLoading())
.doFinally(() -> mView.hideLoading())
.subscribe(new Observer<PublicAccountBean>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(PublicAccountBean publicAccountBean) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
有没有觉得这个代码很长啊,Observer接口里面有四个方法需要重写,有时候我们不想要这么多方法,只想要一个success和一个error方法,怎么办呢?也简单,封装一个BaseObserver。代码如下:
public abstract class BaseObserver<T> implements Observer<T> {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(T t) {
success(t);
}
@Override
public void onError(Throwable e) {
if (e instanceof NetException.ResponseException) {
error((NetException.ResponseException) e);
} else {
onError(new NetException.ResponseException(e, NetException.ERROR.UNKNOWN));
}
}
@Override
public void onComplete() {
}
public abstract void success(T t);
public abstract void error(NetException.ResponseException e);
里面定义了两个抽象方法,一个success;一个error方法,传入一个NetException(自定义的,代码待会贴出来)对象,BaseObserver实现Observer接口,这里是RxJava里面的Observer,不要写错了,实现其中的四个方法。并传入一个请求成功的泛型,在onNext方法中调用success方法,在onError中调用error方法。好吧,我们再看下MainConract调用:
public class MainContract {
/*
* Activity实现的接口
* */
public interface IView extends BaseView {
void doSomething();
}
public static class Prensenter extends BasePresenter<IView> {
private API api;
private Gson gson;
public Prensenter(IView mView) {
super(mView);
api = RetrofitManager.getInstance().createApi(API.class);
gson = new Gson();
}
public void getPublicAccountList() {
api.getPublicAccountList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bindUntilEvent(mView.getLifeCycleSubject(), ActivityEvent.DESTROY))
.doOnSubscribe(disposable -> mView.showLoading())
.doFinally(() -> mView.hideLoading())
.subscribe(new BaseObserver<PublicAccountBean>() {
@Override
public void success(PublicAccountBean publicAccountBean) {
//成功
}
@Override
public void error(NetException.ResponseException e) {
//失败。
}
});
}
}
}
NetException代码:
public class NetException {
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) {
//转换成ResponseException,根据状态码判定错误信息
ResponseException ex;
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
/**
* 传入状态码,根据状态码判定错误信息
*/
ex = new ResponseException(e, ERROR.HTTP_ERROR);
switch (httpException.code()) {
case UNAUTHORIZED:
ex.message = "未验证";
break;
case FORBIDDEN:
ex.message = "服务禁止访问";
break;
case NOT_FOUND:
ex.message = "服务不存在";
break;
case REQUEST_TIMEOUT:
ex.message = "请求超时";
break;
case GATEWAY_TIMEOUT:
ex.message = "网关超时";
break;
case INTERNAL_SERVER_ERROR:
ex.message = "服务器内部错误";
break;
case BAD_GATEWAY:
ex.message = "请求失败";
break;
case SERVICE_UNAVAILABLE:
ex.message = "请求失败";
break;
default:
ex.message = "请求失败";
break;
}
return ex;
} else if (e instanceof JsonParseException
|| e instanceof JSONException
|| e instanceof ParseException) {
ex = new ResponseException(e, ERROR.PARSE_ERROR);
ex.message = "数据解析异常";
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 = "证书验证失败";
return ex;
} else {
ex = new ResponseException(e, ERROR.UNKNOWN);
ex.message = "未知错误";
return ex;
}
}
/**
* 约定异常
*/
public static class ERROR {
/**
* 自定义异常
*/
private static final int UNAUTHORIZED = 401;//请求用户进行身份验证
private static final int UNREQUEST = 403;//服务器理解请求客户端的请求,但是拒绝执行此请求
private static final int UNFINDSOURCE = 404;//服务器无法根据客户端的请求找到资源
private static final int SEVERERROR = 500;//服务器内部错误,无法完成请求。
/**
* 协议出错
*/
public static final int HTTP_ERROR = 1003;
/**
* 未知错误
*/
public static final int UNKNOWN = 1000;
/**
* 解析错误
*/
public static final int PARSE_ERROR = 1001;
/**
* 网络错误
*/
public static final int NETWORD_ERROR = 1002;
/**
* 证书出错
*/
public static final int SSL_ERROR = 1005;
}
/**
* 统一异常类,便于处理
*/
public static class ResponseException extends Exception {
public int code;
public String message;
public ResponseException(Throwable throwable, int code) {
super(throwable);
this.code = code;
}
}
}
这里我只封装了错误信息和code,如果需要其它的信息,可以根据自己的需求添加。结果依旧是一样的哈。只不过Observer只重写了两个方法,另外两个方法可以选择性的重写。代码看起来稍微简洁那么一丢丢。呼,终于写完了,累死我了~
全部代码已经上传到GitHub,欢迎拍砖。代码传送门:RxMvp