【Android】Retrofit+RxJava+OkHttp的基础、封装和项目中的使用
【android】retrofit+rxjava+okhttp的基础、封装和项目中的使用。近些年很火的retrofit+rxjava+okhttp网络请求框架,功能强大,结构合理,使用简单方便。后面还会给大家发自己整理过的retrofit和rxjava、rxandroid和rxbus。希望大家点一下关注,让我这个懒癌患者有动力继续写下去!
本篇分三个部分:基础篇、封装篇和自己项目使用篇,项目是自己公司的app提取的,文章偏长可以分三部分一点点看,当初看了很多优秀的文章然后自己在整理写在印象笔记中,可惜当初没记下借鉴过的文章地址,十分抱歉。
github地址:https://github.com/bigeyechou/networkframe
简单介绍retrofit、okhttp和rxjava之间的关系:
retrofit:retrofit是square公司开发的一款针对android 网络请求的框架(底层默认是基于okhttp 实现)。 okhttp:也是square公司的一款开源的网络请求库。 rxjava :”a library for composing asynchronous and event-based programs using observable sequences for the java vm”(一个在 java vm 上使用可观测的序列来组成异步的、基于事件的程序的库)。rxjava使异步操作变得非常简单。各自职责:retrofit 负责 请求的数据 和 请求的结果,使用 接口的方式 呈现,okhttp 负责请求的过程,rxjava 负责异步,各种线程之间的切换。
基础篇:
一、retrofit写一个网络请求:
1.引入retrofit的包,在build.gradle文件中添加如下配置:
compile 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit compile 'com.google.code.gson:gson:2.6.2'//gson 库 //下面两个是rxjava 和 rxandroid compile 'io.reactivex:rxjava:1.1.0' compile 'io.reactivex:rxandroid:1.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0'//转换器,请求结果转换成model compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'//配合rxjava 使用
2.创建一个retrofit 实例,并且完成相关的配置:
配置了接口的 base_url 和一个 converter , gsonconverterfactory 是默认提供的 gson转换器。
public static final string base_url = "https://api.douban.com/v2/movie/"; retrofit retrofit = new retrofit.builder() .baseurl(base_url) .addconverterfactory(gsonconverterfactory.create()) .build();
3.创建一个接口:
定义了一个方法 gettop250 ,使用 get请求方式,加上@get 标签,标签后面是这个接口的 尾址top250,完整的地址应该是 baseurl+尾址 ,参数 使用@query标签,如果参数多的话可以用@querymap标 签,接收一个map。
使用 post 请求方式时,只需要更改方法定义的标签,用 @post 标签,参数标签用 @field 或者 @body 或者 fieldmap
public interface movieservice { //获取豆瓣top250 榜单 @get("top250") call gettop250 (@query("start") int start , @query("count") int count); @formurlencoded @post("top250") call gettop250 (@field("start") int start , @field("count") int count); }
使用 post 方式时需要注意两点:
- 必须加上 @formurlencoded标签,否则会抛异常。
- 必须要有参数,否则会抛异常, 抛异常的地方如下:
if (isformencoded && !gotfield) { throw methoderror("form-encoded method must contain at least one @field."); }
4.用 retrofit 创建 接口实例 moiveservice 并且调用接口中的方法进行网络请求:
异步方式请求:
//获取接口实例 movieservice movieservice = retrofit.create(movieservice.class); //调用方法得到一个call call call = movieservice.gettop250(0,20); //进行网络请求 call.enqueue(new callback() { @override public void onresponse(call call, response response) { mmovieadapter.setmovies(response.body().subjects); mmovieadapter.notifydatasetchanged(); } @override public void onfailure(call call, throwable t) { t.printstacktrace(); } });
同步方式请求: 返回一个response
response response = call.execute();
二,配合rxjava 使用:
更改定义的接口,返回值不再是一个 call ,而是返回的一个 observble:public interface movieservice { //获取豆瓣top250 榜单 @get("top250") observable gettop250(@query("start") int start, @query("count")int count); }
2.创建 retrofit 的时候添加如下代码:
addcalladapterfactory(rxjavacalladapterfactory.create())
3.添加转换器converter(将 json 转为 javabean):
addconverterfactory(gsonconverterfactory.create())
举实际项目中使用的例子:
retrofit = new retrofit.builder() .client(okhttpbuilder.build()) .addconverterfactory(gsonconverterfactory.create()) .addcalladapterfactory(rxjavacalladapterfactory.create()) .baseurl(base_url) .build();
4.activity 或者 fragment 中传入 subscriber 建立订阅关系:
subscription subscription = movieservice.gettop250(0,20) .subscribeon(schedulers.io()) .observeon(androidschedulers.mainthread()) .subscribe(new subscriber() { @override public void oncompleted() { } @override public void onerror(throwable e) { } @override public void onnext(moviesubject moviesubject) { mmovieadapter.setmovies(moviesubject.subjects); mmovieadapter.notifydatasetchanged(); } });
5.加入rxjava的好处:
- 加入 rxjava 后的网络请求,返回不再是一个 call ,而是一个 observable。
- 在activity / fragment 中传入一个subscriber 建立订阅关系,就可以在 onnext 中处理结果了。
- rxjava 的好处是帮我处理 线程之间的切换,我们可以在指定 订阅的在哪个线程,观察在哪个线程。
- 可以 通过操作符 进行数据变换。
- 整个过程都是链式的,简化逻辑。其中flatmap 操作符 还可以解除多层嵌套的问题。
rxjava 很强大,能帮我处理很多复杂的场景,如果熟练使用的话,那么能提升我们的开发效率。
三,加入 okhttp 配置:
通过okhttpclient 可以配置很多东西,比如 链接超时时间,缓存,拦截器 等等。代码如下:
okhttpclient.builder builder = new okhttpclient.builder(); builder.connecttimeout(default_time_out, timeunit.seconds);//连接 超时时间 builder.writetimeout(default_time_out,timeunit.seconds);//写操作 超时时间 builder.readtimeout(default_time_out,timeunit.seconds);//读操作 超时时间 builder.retryonconnectionfailure(true);//错误重连 // 添加公共参数拦截器 basicparamsinterceptor basicparamsinterceptor = new basicparamsinterceptor.builder() .addheaderparam("username","")//添加公共参数 .addheaderparam("device","") .build(); builder.addinterceptor(basicparamsinterceptor); // 创建retrofit mretrofit = new retrofit.builder() .client(builder.build()) .addcalladapterfactory(rxjavacalladapterfactory.create()) .addconverterfactory(gsonconverterfactory.create()) .baseurl(apiconfig.base_url) .build();
列举项目中用到的如下:
//项目中设置头信息 interceptor headerinterceptor = new interceptor() { @override public response intercept(chain chain) throws ioexception { request originalrequest = chain.request(); request.builder requestbuilder = originalrequest.newbuilder() .addheader("accept-encoding", "gzip") .addheader("accept", "application/json") .addheader("content-type", "application/json; charset=utf-8") .method(originalrequest.method(), originalrequest.body()); requestbuilder.addheader("authorization", "bearer " + baseconstant.token);//添加请求头信息,服务器进行token有效性验证 request request = requestbuilder.build(); return chain.proceed(request); } }; okhttpbuilder.addinterceptor(headerinterceptor); //项目中创建retrofit retrofit = new retrofit.builder() .client(okhttpbuilder.build()) .addconverterfactory(gsonconverterfactory.create()) .addcalladapterfactory(rxjavacalladapterfactory.create()) .baseurl(base_url) .build(); httpservice = retrofit.create(httpservice.class);
封装篇
一,创建一个 统一生成接口实例的管理类 retrofitservicemanager
创建了一个 retrofitservicemanager 类,该类采用 单例模式,在 私有的 构造方法中,生成了 retrofit 实例,并配置了okhttpclient 和一些 公共配置。
提供了一个create()方法,生成 接口实例,接收 class泛型。
代码如下:
public class retrofitservicemanager { private static final int default_time_out = 5;//超时时间 5s private static final int default_read_time_out = 10; private retrofit mretrofit; private retrofitservicemanager(){ // 创建 okhttpclient okhttpclient.builder builder = new okhttpclient.builder(); builder.connecttimeout(default_time_out, timeunit.seconds);//连接超时时间 builder.writetimeout(default_read_time_out,timeunit.seconds);//写操作 超时时间 builder.readtimeout(default_read_time_out,timeunit.seconds);//读操作超时时间 // 添加公共参数拦截器 httpcommoninterceptor commoninterceptor = new httpcommoninterceptor.builder() .addheaderparams("paltform","android") .addheaderparams("usertoken","1234343434dfdfd3434") .addheaderparams("userid","123445") .build(); builder.addinterceptor(commoninterceptor); // 创建retrofit mretrofit = new retrofit.builder() .client(builder.build()) .addcalladapterfactory(rxjavacalladapterfactory.create()) .addconverterfactory(gsonconverterfactory.create()) .baseurl(apiconfig.base_url) .build(); } private static class singletonholder{ private static final retrofitservicemanager instance = new retrofitservicemanager(); } /** * 获取retrofitservicemanager * @return */ public static retrofitservicemanager getinstance(){ return singletonholder.instance; } /** * 获取对应的service * @param service service 的 class * @param * @return */ public t create(class service){ return mretrofit.create(service); } }
接口实例service都可以用这个来生成,代码如下:
mmovieservice = retrofitservicemanager.getinstance().create(movieservice.class);
二,创建接口,通过第一步获取实例
有了可以获取接口实例的方法,然后创建一个接口,代码如下:
public interface movieservice{ //获取豆瓣top250 榜单 @get("top250") observable gettop250(@query("start") int start, @query("count") int count); @formurlencoded @post("/x3/weather") call getweather(@field("cityid") string cityid, @field("key") string key); }
三,创建一个业务loader ,如xxxloder,获取observable并处理相关业务
创建 loader 的原因:每一个api 都写一个接口很麻烦,因此就把 请求逻辑 封装在 一个业务loader 里面,一个 loader 里面可以处理多个api 接口。代码如下:
public class movieloader extends objectloader { private movieservice mmovieservice; public movieloader(){ mmovieservice = retrofitservicemanager.getinstance().create(movieservice.class); } /** * 获取电影列表 * @param start * @param count * @return */ public observable> getmovie(int start, int count){ return observe(mmovieservice.gettop250(start , count)).map(new func1>() { @override public list call(moviesubject moviesubject) { return moviesubject.subjects; } }); } public observable getweatherlist(string cityid,string key){ return observe(mmovieservice.getweather(cityid , key)).map(new func1() { @override public string call(string s) { //可以处理对应的逻辑后在返回 return s; } }); } public interface movieservice{ //获取豆瓣top250 榜单 @get("top250") observable gettop250(@query("start") int start, @query("count")int count); @formurlencoded @post("/x3/weather") call getweather(@field("cityid") string cityid, @field("key") string key); } } 创建一个movieloader,构造方法中生成了mhttpservice,而 service 中可以定义和业务相关的多个api,比如:例子中的httpservice中, 可以定义和电影相关的多个api,获取电影列表、获取电影详情、搜索电影等api,就不用定义多个接口了。 movieloader 是从 objectloader 中继承下来的,objectloader 提取了一些公共的操作。代码如下: /** * 将一些重复的操作提出来,放到父类以免loader 里每个接口都有重复代码 */ public class objectloader { /** * * @param observable * @param * @return */ protected observable observe(observable observable){ return observable .subscribeon(schedulers.io()) .unsubscribeon(schedulers.io()) .observeon(androidschedulers.mainthread()); } }
四,activity/fragment 中的调用
创建loader实例:
mmovieloader = new movieloader();
通过loader 调用方法获取结果,代码如下:
/** * 获取电影列表 */ private void getmovielist(){ mmovieloader.getmovie(0,10).subscribe(new action1>() { @override public void call(list movies) { mmovieadapter.setmovies(movies); mmovieadapter.notifydatasetchanged(); } }, new action1() { @override public void call(throwable throwable) { log.e("tag","error message:"+throwable.getmessage()); } }); }
五,统一处理结果和错误
1.统一处理请求结果:
现实项目中,所有接口的返回结果都是同一格式,如:
{ "status": 200, "message": "成功", "data": {} }
在请求api 接口的时候,只关心想要的数据,也就上面的 data{ },其他的东西不太关心,请求失败 的时候可以根据 status 判断进行 错误处理。
包装返回结果:首先需要根据服务端定义的 json 结构创建一个 baseresponse 类,代码如下:
/** * 网络请求结果 基类 */ public class baseresponse { public int status; public string message; public t data; public boolean issuccess(){ return status == 200; } }
有了统一的格式数据后,我们需要 剥离出data{ }返回给 上层调用者,创建一个 payload 类,代码如下:
/** * 剥离 最终数据 */ public class payload implements func1{ @override public t call(baseresponse tbaseresponse) {//获取数据失败时,包装一个fault 抛给上层处理错误 if(!tbaseresponse.issuccess()){ throw new fault(tbaseresponse.status,tbaseresponse.message); } return tbaseresponse.data; } }
payload 继承自 func1,接收一个baseresponse , 就是接口返回的 json 数据结构,返回的是 t,就是data{ },判断是否请求成功,请求成功 返回data,请求失败 包装成一个 fault 返回给上层统一处理错误。
在loader类里面获取结果后,通过map 操作符剥离数据。代码如下:
public observable> getmovie(int start, int count){ return observe(mmovieservice.gettop250(start,count)) .map(new payload>()); }
2.统一处理错误:
在payload 类里面,请求失败时,抛出了一个fault 异常给上层,我在activity/fragment 中拿到这个异常,然后判断错误码,进行异常处理。在onerror () 中添加。
对应 错误码 处理 相应的错误,代码如下:
public void call(throwable throwable) { log.e("tag","error message:"+throwable.getmessage()); if(throwable instanceof fault){ fault fault = (fault) throwable; if(fault.geterrorcode() == 404){ //错误处理 }else if(fault.geterrorcode() == 500){ //错误处理 }else if(fault.geterrorcode() == 501){ //错误处理 } } }
六,添加公共参数
实际项目中,每个接口都有一些基本的相同的参数,我们称之为公共参数,比如:userid、usertoken、username、deviceid等等,我们不必每个接口都去写,可以写一个拦截器,在拦截器里面拦截请求,为每个请求都添加相同的公共参数。
拦截器代码如下:
/* * 拦截器 * * 向请求头里添加公共参数 */ public class httpcommoninterceptor implements interceptor { private map mheaderparamsmap = new hashmap<>(); public httpcommoninterceptor() { } @override public response intercept(chain chain) throws ioexception { log.d("httpcommoninterceptor","add common params"); request oldrequest = chain.request(); // 添加新的参数,添加到url 中 /*httpurl.builder authorizedurlbuilder = oldrequest.url().newbuilder() .scheme(oldrequest.url().scheme()) .host(oldrequest.url().host());*/ // 新的请求 request.builder requestbuilder = oldrequest.newbuilder(); requestbuilder.method(oldrequest.method(), oldrequest.body()); //添加公共参数,添加到header中 if(mheaderparamsmap.size() > 0){ for(map.entry params:mheaderparamsmap.entryset()){ requestbuilder.header(params.getkey(),params.getvalue()); } } request newrequest = requestbuilder.build(); return chain.proceed(newrequest); } public static class builder{ httpcommoninterceptor mhttpcommoninterceptor; public builder(){ mhttpcommoninterceptor = new httpcommoninterceptor(); } public builder addheaderparams(string key, string value){ mhttpcommoninterceptor.mheaderparamsmap.put(key,value); return this; } public builder addheaderparams(string key, int value){ return addheaderparams(key, string.valueof(value)); } public builder addheaderparams(string key, float value){ return addheaderparams(key, string.valueof(value)); } public builder addheaderparams(string key, long value){ return addheaderparams(key, string.valueof(value)); } public builder addheaderparams(string key, double value){ return addheaderparams(key, string.valueof(value)); } public httpcommoninterceptor build(){ return mhttpcommoninterceptor; } } }
以上就是添加公共参数的拦截器,在 retrofitservicemanager 类里面加入okhttpclient 配置就好了。
代码如下:
// 添加公共参数拦截器 httpcommoninterceptor commoninterceptor = new httpcommoninterceptor.builder() .addheaderparams("paltform","android") .addheaderparams("usertoken","1234343434dfdfd3434") .addheaderparams("userid","123445") .build(); builder.addinterceptor(commoninterceptor);
项目使用篇 —–>插入广告!本项目来源于金融研习社app,金融理财类的在线教育
项目是基于rxjava1
1.引入依赖:
compile 'com.squareup.retrofit2:retrofit:2.0.2' compile 'com.squareup.retrofit2:converter-gson:2.0.2' compile 'io.reactivex:rxandroid:1.2.0' compile 'io.reactivex:rxjava:1.1.5' compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2' compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
2.创建一个httpservice接口:
public interface httpservice { /** * 获取用户详细资料 */ @post("api/xxx/getuseralldetails") observable getuseralldetails(@body getuseralldetailsrequestbean bean); /** * @param apkurl 下载地址 */ @get() @streaming call downloadnewapk(@url string apkurl); /** * 获取推广大使分享图片 */ @get("api/xxx/invitedimage") observable getinvitedimage(@querymap map map); }
3.创建http请求类,并在里面初始化并配置retrofit和okhttp:
public class httpmethods { public string tag = "httpmethods"; public static final string cache_name = "xxx"; public static string base_url = urlconstant.base_url; private static final int default_connect_timeout = 30; private static final int default_write_timeout = 30; private static final int default_read_timeout = 30; private retrofit retrofit; private httpservice httpservice; /** * 请求失败重连次数 */ private int retry_count = 0; private okhttpclient.builder okhttpbuilder; //构造方法私有 private httpmethods() { //手动创建一个okhttpclient并设置超时时间 okhttpbuilder = new okhttpclient.builder(); /** * 设置缓存 */ file cachefile = new file(applicationcontext.context.getexternalcachedir(), cache_name); cache cache = new cache(cachefile, 1024 * 1024 * 50); interceptor cacheinterceptor = new interceptor() { @override public response intercept(chain chain) throws ioexception { request request = chain.request(); if (!netutil.isnetworkconnected()) { request = request.newbuilder() .cachecontrol(cachecontrol.force_cache) .build(); } response response = chain.proceed(request); if (!netutil.isnetworkconnected()) { int maxage = 0; // 有网络时 设置缓存超时时间0个小时 response.newbuilder() .header("cache-control", "public, max-age=" + maxage) .removeheader(cache_name)// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效 .build(); } else { // 无网络时,设置超时为4周 int maxstale = 60 * 60 * 24 * 28; response.newbuilder() .header("cache-control", "public, only-if-cached, max-stale=" + maxstale) .removeheader(cache_name) .build(); } return response; } }; okhttpbuilder.cache(cache).addinterceptor(cacheinterceptor); /** * 设置头信息 */ interceptor headerinterceptor = new interceptor() { @override public response intercept(chain chain) throws ioexception { request originalrequest = chain.request(); request.builder requestbuilder = originalrequest.newbuilder() .addheader("accept-encoding", "gzip") .addheader("accept", "application/json") .addheader("content-type", "application/json; charset=utf-8") .method(originalrequest.method(), originalrequest.body()); requestbuilder.addheader("authorization", "bearer " + baseconstant.token);//添加请求头信息,服务器进行token有效性验证 request request = requestbuilder.build(); return chain.proceed(request); } }; okhttpbuilder.addinterceptor(headerinterceptor); // if (buildconfig.debug) { httplogginginterceptor logginginterceptor = new httplogginginterceptor(new httplogginginterceptor.logger() { @override public void log(string message) { logger.d(message); } }); logginginterceptor.setlevel(httplogginginterceptor.level.body); //设置 debug log 模式 okhttpbuilder.addinterceptor(logginginterceptor); // } /** * 设置超时和重新连接 */ okhttpbuilder.connecttimeout(default_connect_timeout, timeunit.seconds); okhttpbuilder.readtimeout(default_write_timeout, timeunit.seconds); okhttpbuilder.writetimeout(default_read_timeout, timeunit.seconds); //错误重连 okhttpbuilder.retryonconnectionfailure(true); retrofit = new retrofit.builder() .client(okhttpbuilder.build()) .addconverterfactory(gsonconverterfactory.create())//json转换成javabean .addcalladapterfactory(rxjavacalladapterfactory.create()) .baseurl(base_url) .build(); httpservice = retrofit.create(httpservice.class); } //在访问httpmethods时创建单例 private static class singletonholder { private static final httpmethods instance = new httpmethods(); } //获取单例 public static httpmethods getinstance() { return singletonholder.instance; } /** * 获取retrofit */ public retrofit getretrofit() { return retrofit; } public void changebaseurl(string baseurl) { retrofit = new retrofit.builder() .client(okhttpbuilder.build()) .addconverterfactory(gsonconverterfactory.create()) .addcalladapterfactory(rxjavacalladapterfactory.create()) .baseurl(baseurl) .build(); httpservice = retrofit.create(httpservice.class); } /** * 获取httpservice */ public httpservice gethttpservice() { return httpservice; } /** * 设置订阅 和 所在的线程环境 */ public void tosubscribe(observable o, subscriber s) { o.subscribeon(schedulers.io()) .unsubscribeon(schedulers.io()) .observeon(androidschedulers.mainthread()) .retry(retry_count)//请求失败重连次数 .subscribe(s); } }
4.设置回调:
调用者自己对请求数据进行处理 成功时 通过result是否等于1分别回调onsuccees和onfault,默认处理了401错误转登录。
public class onsuccessandfaultsub extends subscriber implements progresscancellistener { /** * 是否需要显示默认loading */ private boolean showprogress = true; private onsuccessandfaultlistener monsuccessandfaultlistener; private context context; private waitprogressdialog progressdialog; /** * @param monsuccessandfaultlistener 成功回调监听 */ public onsuccessandfaultsub(onsuccessandfaultlistener monsuccessandfaultlistener) { this.monsuccessandfaultlistener = monsuccessandfaultlistener; } /** * @param monsuccessandfaultlistener 成功回调监听 * @param context 上下文 */ public onsuccessandfaultsub(onsuccessandfaultlistener monsuccessandfaultlistener, context context) { this.monsuccessandfaultlistener = monsuccessandfaultlistener; this.context = context; progressdialog = new waitprogressdialog(context, this); } /** * @param monsuccessandfaultlistener 成功回调监听 * @param context 上下文 * @param showprogress 是否需要显示默认loading */ public onsuccessandfaultsub(onsuccessandfaultlistener monsuccessandfaultlistener, context context, boolean showprogress) { this.monsuccessandfaultlistener = monsuccessandfaultlistener; this.context = context; progressdialog = new waitprogressdialog(context, this); this.showprogress = showprogress; } private void showprogressdialog() { if (showprogress && null != progressdialog) { progressdialog.show(); } } private void dismissprogressdialog() { if (showprogress && null != progressdialog) { progressdialog.dismiss(); } } /** * 订阅开始时调用 * 显示progressdialog */ @override public void onstart() { showprogressdialog(); } /** * 完成,隐藏progressdialog */ @override public void oncompleted() { dismissprogressdialog(); progressdialog = null; } /** * 对错误进行统一处理 * 隐藏progressdialog */ @override public void onerror(throwable e) { try { if (e instanceof sockettimeoutexception) {//请求超时 } else if (e instanceof connectexception) {//网络连接超时 monsuccessandfaultlistener.onfault("网络连接超时"); } else if (e instanceof sslhandshakeexception) {//安全证书异常 monsuccessandfaultlistener.onfault("安全证书异常"); } else if (e instanceof httpexception) {//请求的地址不存在 int code = ((httpexception) e).code(); if (code == 504) { monsuccessandfaultlistener.onfault("网络异常,请检查您的网络状态"); } else if (code == 404) { monsuccessandfaultlistener.onfault("请求的地址不存在"); } else { monsuccessandfaultlistener.onfault("请求失败"); } } else if (e instanceof unknownhostexception) {//域名解析失败 monsuccessandfaultlistener.onfault("域名解析失败"); } else { monsuccessandfaultlistener.onfault("error:" + e.getmessage()); } } catch (exception e2) { e2.printstacktrace(); } finally { log.e("onsuccessandfaultsub", "error:" + e.getmessage()); dismissprogressdialog(); progressdialog = null; } } /** * 当result等于1回调给调用者,否则自动显示错误信息,若错误信息为401跳转登录页面。 */ @override public void onnext(responsebody body) { try { final string result = compressutils.decompress(body.bytestream()); log.e("body", result); jsonobject jsonobject = new jsonobject(result); int resultcode = jsonobject.getint("errorcode"); if (resultcode == 1) { monsuccessandfaultlistener.onsuccess(result); } else { string errormsg = jsonobject.getstring("errormessage"); monsuccessandfaultlistener.onfault(errormsg); log.e("onsuccessandfaultsub", "errormsg: " + errormsg); } } catch (exception e) { e.printstacktrace(); } } /** * 取消progressdialog的时候,取消对observable的订阅,同时也取消了http请求 */ @override public void oncancelprogress() { if (!this.isunsubscribed()) { this.unsubscribe(); } } }
*请求服务loading关闭监听 */ public interface progresscancellistener { void oncancelprogress(); }
5.请求的用法:
建议分类成不同的api,以便快速查找
api里面进行观察者和被观察者的订阅
private void getuserdata() { onsuccessandfaultlistener l = new onsuccessandfaultlistener() { @override public void onsuccess(string result) {//成功回调 yxspreference.setuserdata(result); userdatabean = gsonutils.fromjson(result, userdetailresponsebean.class); fulldata(); } @override public void onfault(string errormsg) {//失败的回调 snackbarmanager.showshortmsg(getactivity(), errormsg); } }; userapi.getuseralldetails(new onsuccessandfaultsub(l) , yxspreference.getmemberid() ); }
onsuccessandfaultsub 继承 subscriber
public class userapi { /** * 获取用户详细信息 */ public static void getuseralldetails(subscriber subscriber, int memberid) { getuseralldetailsrequestbean bean = new getuseralldetailsrequestbean(); bean.getdata().setmemberid(memberid); observable observable = httpmethods.getinstance().gethttpservice().getuseralldetails(bean); //在httpserver中 httpmethods.getinstance().tosubscribe(observable, subscriber); } }