使用MVP+Retrofit+RxJava实现的的Android Demo (下)使用Retrofit+RxJava处理网络请求
来源:互联网 发布:瞩目视频会议软件下载 编辑:程序博客网 时间:2024/04/30 18:17
上篇文章介绍了MVP的实现,这篇文章将介绍Retrofit+RxJava实现网络请求。
先重新贴一下需求
从网络Api获取Json格式的笑话数据,通过列表方式显示,列表分页显示,当上拉到最后一个数据是,自动从网络加载数据并显示,在顶端进行下拉式刷新数据。
最终效果图:
App下载地址: http://a.app.qq.com/o/simple.jsp?pkgname=chenyu.jokes
微信扫描下载APP:
源码地址: https://github.com/zhongchenyu/jokes
Retrofit的使用
建立Api接口文件
创建ServiceAPI接口文件,代码如下:
package chenyu.jokes.network;import chenyu.jokes.model.Response;import retrofit2.http.GET;import retrofit2.http.Query;import rx.Observable;/** * Created by chenyu on 2017/3/3. */public interface ServerAPI { String ENDPOINT = "http://119.23.13.228"; @GET("/content.php") Observable<Response> getJokes( @Query("page") int page ); @GET("/img.php") Observable<Response> getFunPic( @Query("page") int page ); @GET("/blacklist.json") Observable<Response> getBlackList();}
ENDPOINT 是服务器的基础地址,后面声明了3个Api接口,我们只看下第一个,后面的类似。
@GET("/content.php") Observable<Response> getJokes( @Query("page") int page );
注解@GET("/content.php")
表示请求是GET方式,访问的地址是ENDPOINT加括号里的字符串,即http://119.23.13.228/content.php 。
函数getJokes 带有一个参数page,page被注解@Query("page")
修饰,表示发送此GET请求时会带一个参数page,其值为getJokes调用时传递的值。
返回类型Observable<Response>
表示返回值是个RxJava的Observable类,泛型为之前定义的Model类Response。这样对于Http请求后返回的Json数据,会解析成Response对象,并转换成Observable对象,方便后续通过RxJava进行异步处理。
Response类:
package chenyu.jokes.model;import com.fasterxml.jackson.annotation.JsonIgnoreProperties;import com.fasterxml.jackson.annotation.JsonProperty;import org.parceler.Parcel;/** * Created by chenyu on 2017/3/3. */@Parcel @JsonIgnoreProperties(ignoreUnknown = true) public class Response { public Result result; @JsonProperty("error_code") public int errorCode; public String reason;}
实现API接口
声明了接口之后,还需要对接口进行实现,我们在APP类的onCreate里进行,代码如下:
package chenyu.jokes.app;import android.support.multidex.MultiDexApplication;import android.text.Html;import android.text.Spanned;import chenyu.jokes.network.ServerAPI;import okhttp3.OkHttpClient;import okhttp3.logging.HttpLoggingInterceptor;import retrofit2.Retrofit;import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;import retrofit2.converter.jackson.JacksonConverterFactory;/** * Created by chenyu on 2017/3/3. */public class App extends MultiDexApplication { private static ServerAPI serverAPI; @Override public void onCreate(){ super.onCreate(); HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(logging).build(); serverAPI = new Retrofit.Builder() .baseUrl(ServerAPI.ENDPOINT) .addConverterFactory(JacksonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(httpClient) .build() .create(ServerAPI.class); } public static ServerAPI getServerAPI() { return serverAPI; }
为了调试方便,加了日志拦截器,首先创建一个HttpLoggingInterceptor,将日志级别设为最高级别BODY,会将HTTP请求和相应几乎所有内容都记录下来。再创建一个OKHttpClient,添加刚建立的日志拦截器。
接下来就是要实例化serverAPI了,这里通过new一个Retrofit.Builder()来建立。
.baseUrl(ServerAPI.ENDPOINT)
添加API基础地址; .addConverterFactory(JacksonConverterFactory.create())
添加 对返回的Json数据进行解析的Factory,需要配合我们在Model类种添加的Jackson注解。 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
添加RxJava适配工厂,将解析的数据转换成RxJava中的类。 .client(httpClient)
添加前面建立的包含日志拦截的httpClient。 .build().create(ServerAPI.class);
创建并实现ServiceAPI.class中声明的函数。
这样ServiceAPI就已经实例化了,最后公开一个getServerAPI(),以便在需要的地方获取ServiceAPI实例。
接口调用和RxJava处理
我们用的MVP架构,网络请求是在Presenter中处理的,这里我们看一下JokePresenter类是如何获取并处理joke接口的数据的。
上篇文件已经讲过,在Presenter的onCreate()函数中注册网络请求,再调用start(int requestId)即可完成网络请求,代码如下:
restartableFirst(GET_JOKES, new Func0<Observable<ArrayList<Data>>>() { @Override public Observable<ArrayList<Data>> call() { return App.getServerAPI().getJokes(mPage).subscribeOn(io()).observeOn(mainThread()) .flatMap(errorCodeProcess); } }, new Action2<JokeFragment, ArrayList<Data>>() { @Override public void call(JokeFragment jokeFragment, ArrayList<Data> data) { jokeFragment.onItemsNext(data); } }, new Action2<JokeFragment, Throwable>() { @Override public void call(JokeFragment jokeFragment, Throwable throwable) { jokeFragment.onItemsError(throwable); } } );
restartableFirst有4个参数,第一个为请求的ID,在第二个参数中重写了Func0的call()函数,Func0是RxJava的接口,代表要实现的函数没有输入参数,但是有返回值,我们具体看一下: App.getServerAPI().getJokes(mPage)
调用上一节中讲到的API接口,请求地mPage页的数据。
.subscribeOn(io()).observeOn(mainThread())
这里是RxJava的线程切换,同时也用到了RxAndroid中的io()和mainThread(),分别代表IO线程和主线程。
我们知道,网络请求是耗时任务,不能放在主线程里,但是非主线程是不能更新UI的,更新UI只能在主线程里进行。如果不用RxJava,则需要使用Thread结合Handle来处理,需要各种嵌套和回调等,代码易读性就下降了。
而RxJava的优势这时候就体现出来了,调用两个简短的函数就完成了网络请求和UI更新的线程切换,并且可以保持代码的链式结构不中断,代码简洁明了。
至于subscribeOn和observeOn的含义,设计到观察者模式,RxJava就是基于观察者模式的,API返回的是Observable,可以理解成被观察对象,subscribeOn代表订阅观察对象时使用的线程,也就是网络请求产生观察对象的过程,在我们这段代码中就是控制网络请求使用的线程。而observeOn代表对Observable观察处理用的线程,在这里就是处理API返回结果,并通知View层进行更新时使用的线程。
.flatMap(errorCodeProcess)
是用来对返回数据进行预处理的,API返回的数据保护error_code,如果error_code不为0,则代表数据出错,这时就可以直接抛出异常,进入异常处理流程,跳过UI更新;而如果error_code不为0,代表数据正常,这时我们也对数据进行转换,提取出Response中的Data信息,交给后续处理。
flatMap是RxJava的操作符,用来对Observable进行处理,返回的对象还是Observable类型,看下errorCodeProcess的代码:
private Func1 errorCodeProcess = new Func1<Response, Observable<ArrayList<Data>>>() { @Override public Observable<ArrayList<Data>> call(Response response) { if(response.errorCode !=0) { return Observable.error(new Throwable(response.reason)); } return Observable.just(response.result.data); } };
这里重写了Func1的call函数,Func1是Rxjava中的接口,代表要实现的函数有一个输入参数,一个返回值。这里的输入时getJokes函数的返回值,判断下response的errorCode,如果非0,则用response的reason生成一个Throwable并通过Observale.error()抛出;如果errorCode为0,则提取出response中的data,生成一个新的Observable作为返回值。
restartableFirst的第三个参数重写了RxJava的Action2接口,代表有两个输入参数,没有返回值,这里两个参数分别是JokeFragment和ArrayList,其实就是View层和Model层。Action2会在数据请求处理成功后执行,通知View层更加返回的Model数据更新UI。
restartableFirst的第四个参数是可选参数,也是重写了Action2,会在网络请求出错后执行,用来处理异常,形式和第三个参数基本一致,只是把Model换成了Throwable,请求过程中出现的异常,包括Http异常,还有我们自定义的在errorCode不为0时抛出的异常,都会在这里处理。
这一部分是Nucleus MVP框架和RxJava结合实现的,如果再结合Lambda表达式,代码会变得异常简洁、清晰,看效果:
可以看出,MVP的代码分割,Retrofit+RxJava的接口链式调用,再加上Lambda表达式的缩减,简单几行代码,就能讲清楚网络请求、数据处理、线程切换、UI更新、异常处理的整套流程,在后续项目维护和再开发中提供很大的便利,如果加以封装,也能大大减少代码工作量。
- 使用MVP+Retrofit+RxJava实现的的Android Demo (下)使用Retrofit+RxJava处理网络请求
- mvp下rxjava+retrofit的登录网络请求demo
- Android使用RxJava+Retrofit请求网络的小Demo
- 使用MVP+Retrofit+RxJava实现的的Android Demo (上)使用Nuclues库实现MVP
- MVP+Rxjava+Retrofit的使用
- Android中的RxJava,Retrofit,MVP的使用
- MVP+Retrofit+RxJava的demo
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
- MVP+Retrofit+RxJava 使用
- Android--MVP+Retrofit+Rxjava的实现
- 优雅的使用MVP+RxJava+Retrofit框架
- MVP+retrofit+rxjava+Knife的简单使用
- Mvp-Retrofit-Rxjava-Rxbus的初步使用
- MVP(Retrofit+RXJava)实现网络请求
- android+MVP+Retrofit+RxJava做网络请求
- Retrofit+RxJava的使用
- Retrofit+RXJava的使用
- 使用rxjava,retrofit,okhttp实现mvp模式的数据解析
- NYOJ-305-表达式求值(第四届河南省程序设计大赛C题(模拟+栈||递归)(sscanf函数的应用))
- ios控制器之间传值-单例传值
- Oracle insert大数据量经验之谈
- Docker的使用--制作自己的镜像(四)
- Ubuntu下指令-查看端口的占用情况以及抓包
- 使用MVP+Retrofit+RxJava实现的的Android Demo (下)使用Retrofit+RxJava处理网络请求
- Laravel5.2版本后更新的中间件组部分
- Java实现动态代理的两种方式
- 初识docker
- cpu load过高问题排查
- 菜狗的C++ primer读书笔记:第七章 类
- Android studio 启动自学模式
- QT5.7操作word
- Android RecyclerView 使用完全解析 体验艺术般的控件