这是一篇浅显的Rxjava+Retrofit文章,从初学者出发,感觉如果工作中没有充足发挥自学技能的项目,直接去看大佬们写的很深入的讲解,特别容易遗忘、懵甚至不理解,所以我决定写一篇浅显的使用Rxjava+Retrofit的文章。
所需依赖库:
compile"io.reactivex.rxjava2:rxjava:2.1.1"
compile'io.reactivex.rxjava2:rxandroid:2.0.2'
compile'com.squareup.retrofit2:retrofit:2.3.0'
compile'com.squareup.retrofit2:converter-gson:2.3.0'
compile'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
一、 retrofit的使用
首先我们要先了解一下retrofit,他是这个组合负责网络访问的部分,获取rxjava的被观察者。
1. 根据要访问的数据创建实体类,我访问的是“聚合数据”提供的新闻头条链接(“http://v.juhe.cn/toutiao/index?type=top&key=APPKEY”),获取的数据格式为:
根据数据创建实体类:
public class NewsBeen<T> {
@SerializedName("reason")
private String reason;
@SerializedName("result")
private T result;
@SerializedName("error_code")
private int error_code;
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
public int getError_code() {
return error_code;
}
public void setError_code(int error_code) {
this.error_code = error_code;
}
}
public class ResultBean {
private String stat;
private List<DataBean> data;
public String getStat() {
return stat;
}
public void setStat(String stat) {
this.stat = stat;
}
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
public static class DataBean {
private String uniquekey;
private String title;
private String date;
private String category;
private String author_name;
private String url;
private String thumbnail_pic_s;
private String thumbnail_pic_s02;
private String thumbnail_pic_s03;
public String getUniquekey() {
return uniquekey;
}
public void setUniquekey(String uniquekey) {
this.uniquekey = uniquekey;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getAuthor_name() {
return author_name;
}
public void setAuthor_name(String author_name) {
this.author_name = author_name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getThumbnail_pic_s() {
return thumbnail_pic_s;
}
public void setThumbnail_pic_s(String thumbnail_pic_s) {
this.thumbnail_pic_s = thumbnail_pic_s;
}
public String getThumbnail_pic_s02() {
return thumbnail_pic_s02;
}
public void setThumbnail_pic_s02(String thumbnail_pic_s02) {
this.thumbnail_pic_s02 = thumbnail_pic_s02;
}
public String getThumbnail_pic_s03() {
return thumbnail_pic_s03;
}
public void setThumbnail_pic_s03(String thumbnail_pic_s03) {
this.thumbnail_pic_s03 = thumbnail_pic_s03;
}
}
}
实体类创建没什么好说的,可以直接拿参数GsonFormat一下就好了。
2. 然后定义接口
public interface NewsService {
@GET("index")
Observable<NewsBeen<ResultBean>> getNews(@Query("type") String type, @Query("key") String ley);
@GET("index?type=top&key=28aa4ac2a689c881a4e6e51cf918d695")
Observable<NewsBeen<ResultBean>> getNews();
}
接口中两个方法效果一样,@后跟网络请求方法,一般为GET和POST,就是GET和POST请求,括号中为拼接的链接,比如这条链接:http://v.juhe.cn/toutiao/index?type=top&key=APPKEY,我们把“http://v.juhe.cn/toutiao/”当做BaseUrl,那请求后括号中的内容加方法参数中的内容拼接起来就是要访问的链接,这要注意以下几点:
1. 其中BaseUrl的结尾必须为“/”,不然请求链接时会报错。
2. 请求方法后括号可以通过(index/{id})的写法,在方法参数中获取id,方法参数的处理为(@Path(”id”) int id),比如传过来123,则此回调与baseurl拼接的链接就为“index/123”。
3. 如果链接为http://v.juhe.cn/toutiao/index?type=top&key=APPKEY,除了傻瓜式把后边全放到请求方法后,也可以像方法一中那样更加灵活的获取:(@Query("type")String type, @Query("key")String ley);
注:像@Paht和@Query这些注解的具体使用可以在走通整个网络框架后再去慢慢学习了解,如果当前正在处理一个项目,且所需要的网络连接比较特殊,也可以专门去搜一下这块。
3.接下来定义一个OkHttpClient,进行一些访问配置。
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {//添加网络访问Header
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
builder.addHeader("token", "123");
return chain.proceed(builder.build());
}
})
.addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
//获取网络访问错误信息
}
}).setLevel(HttpLoggingInterceptor.Level.BASIC))
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)//链接超时
.readTimeout(TIMEOUT,TimeUnit.SECONDS)//读取超时
.build();
一般使用retrofit访问网络需要添加如上代码中的HttpLoggingInterceptor简化调试,需添加依赖:
compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'
4. 获取接口类
NewsService service = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(buildGson()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(httpClient)
.build()
.create(NewsService.class);
.addConverterFactory(GsonConverterFactory.create(buildGson()))这句代码是通过gson解析网络获取的数据,不加应该是会报错的,其中Gson的定义:
Gson buildGson() = GsonBuilder()
.serializeNulls()
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
.create();
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())这句代码是添加对Rxjava2的支持,注意是Rxjava2,如果集成的是Rxjava要对应修改这里。
5. 最后通过接口返回Rxjava的被观察者
Observable<NewsBeen<ResultBean>> observable = RetrofitFactory.getNews().getNews("top", "123456");
这样Retrofit的工作就完成了,接下来就看Rxjava部分,Rxjava同样是很优秀内容很多的框架,这次就先依着简单的实现效果看一下。
二、 Rxjava的使用
Rxjava主要分三部分,被观察者(Observable)、观察者(Observer)和链接二者的subscribe(),当被观察者(Observable)和观察者(Observer)被subscribe()链接起来的时候,如果被观察者(Observable)发生变化,被观察者(Observable)就能感知得到,这这篇文章中就是,当retrofit网络访问获取到数据的时候,被观察者(Observable)获取得到实例,观察者(Observer)观察者就能收到此消息,处理被观察中实例中获取的数据。
1. 刚才我们获取了被观察者(Observable),现在我们再来定义一个观察者
public abstract class BaseObserver<T> implements Observer<NewsBeen<T>> {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull NewsBeen<T> tNewsBeen) {
if (tNewsBeen.getError_code()==0) {
T t = tNewsBeen.getResult();
getDatas (t);
}else {
//在此可处理获取失败逻辑
}
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
protected abstract void getDatas(T t);
}
继承Observer接口,实现其中的方法,创建观察者基类,成功获取数据调用getDatas(T t)方法将数据传出去。 2.这样观察者和被观察者都有了,但要注意一点,网络访问为耗时操作,获取到数据很多要在主线程接收展示,所以要加上线程转换。
public class RxSchedulers {
public static <T> ObservableTransformer<T,T> compose(){
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
return upstream
.subscribeOn(Schedulers.io())
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(@NonNull Disposable disposable) throws Exception {
//订阅开始前调用,可以在此做一些网络获取数据环境的判断
}
})
.observeOn(AndroidSchedulers.mainThread());
}
};
}
}
3.最后把观察者和被观察者链接起来。
observable.compose(RxSchedulers.<NewsBeen<ResultBean>>compose()).subscribe(new BaseObserver<ResultBean>(MainActivity.this) {
@Override
protected void getDatas (ResultBean resultBean) {
//最终从自定义的观察者基类的抽象方法中获取到网络数据
}
});
经过以上代码就可以搭建一个最基本的Rxjava+Retrofit网络框架,诚然,我的水平相比播客中许多大佬的水平要相差甚远,网上随便一搜就有很多详细到源码,各种重写方法的高阶播客,感觉那些都不太适合初学者,我的学习方法就是找到一篇简单的使用播客,先把效果做出来,然后根据效果再去扩展着学习,希望我的这篇播客能帮助更多像我一样,独自一人向更高艰难前进的人,如果有幸被哪位大佬看见,也希望能获得指点一二。