之前自己实现了一个新闻类阅读APP,最近想使用当下流行的Retrofit + Rxjava + RxAndroid + MVP架构来重构一下,本文以每日一文作为数据源API做一个简单的示例,来介绍一下如何使用Retrofit + Rxjava + RxAndroid来实现网络数据请求与解析。
一、配置
在你项目的build.gradle文件中加入如下配置:
//rxjava
compile 'io.reactivex:rxandroid:1.2.0'
compile 'io.reactivex:rxjava:1.1.5'
//retrofit
compile 'com.google.code.gson:gson:2.7'
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.okhttp:okhttp:2.4.0'
二、生成数据实体
把API返回的Json数据通过Android Studio的GsonFormat插件进行转换生成数据实体类DailyReadEntity(自动构建的代码,很长就不往上贴了)
三、创建请求service接口
今日文章
url:https://interface.meiriyiwen.com/article/today?dev=1
特定日期文章
url:https://interface.meiriyiwen.com/article/day?dev=1&date= + 日期
url 示例:https://interface.meiriyiwen.com/article/day?dev=1&date=20170216
public interface DailyReadService {
@GET("article/today?dev=1")
Observable<DailyReadEntity> getTodayDailyRead();
@GET("article/day?dev=1&date=")
Observable<DailyReadEntity> getParticularDayDailyRead(@Query("date") int date );
}
四、构建retrofit实例并创建请求service
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://interface.meiriyiwen.com/") //主机URL
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
DailyReadService dailyReadService = retrofit.create(DailyReadService.class);
五、调用请求service中定义的方法请求数据
dailyReadService.getTodayDailyRead()
.subscribeOn(Schedulers.io()) //在新线程里面处理网络请求
.observeOn(AndroidSchedulers.mainThread()) //在主线程里面接受返回的数据
.subscribe(new Subscriber<DailyReadEntity>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(DailyReadEntity today) {
Log.d(TAG,"onNext daily = " + today.toString());
}
});
dailyReadService.getParticularDayDailyRead(20170511)
.subscribeOn(Schedulers.io()) //在新线程里面处理网络请求
.observeOn(AndroidSchedulers.mainThread()) //在主线程里面接受返回的数据
.subscribe(new Subscriber<DailyReadEntity>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(DailyReadEntity particularDay) {
Log.d(TAG,"onNext particularDay = " + particularDay.toString());
}
});
小结:
我自己在实践过程中所遇到的问题是在实现请求服务接口的时候@Path和@Query等接口的使用,查看了一下Retrofit的官方文档和具体接口的注释很快就解决了。另外,这是一个与网络相关的功能,是一个耗时任务需要在子线程中执行。这个时候就看出来这套框架的优点了,你只需调用subscribeOn在新线程中请求,然后调用observeOn在主线程中接受数据,两行代码就解决了,再也不用自己去创建新的线程然后再通过handler通知主线程来刷新数据了。
最后要吐槽一下,昨天在用网易新闻的一个频道实现逻辑做测试的时候始终抛出retrofit2.adapter.rxjava.HttpException: HTTP 403 Forbidden异常,印象里就成功了一把。检查了很多遍也做了很多尝试都不行,耗了一个下午,log中也无其他异常,最后换了一个其他频道,终于可以正常解析了,原来是服务器异常导致的。这个故事告诉我们,有的时候你需要换个角度思考问题。