前言
现在的软件开发世界里已经出现了很多好用高效的开发框架,作为程序员的我们要随时保持警惕,紧跟潮流,学会使用大牛们所开发出来的东西,目前市场上对应用RxJava+Retrofit+Okhttp(个人认为优点主要在业务处理与逻辑的简化,小伙伴可以细心琢磨哦)已经成为一种主流,不会的小伙伴可以一起探讨学习哦。
这个我推荐大家看看四篇文章
那么接下来如何运用RxJava+Retrofit+Okhttp完成一次网络请求呢,之前我也看了很多文章,但是做为刚入门的我使用起来还是陌生,有些地方还是不太明白,这里不得不感谢一下我的同事,他这两天确实拓宽了我很多的眼界,让我对这个框架大致有了一个认识。
按照传统网络处理方式,我们一般或通过okhttp提交请求,对与请求后的数据处理,我想大多数人都是利用Handler机制,没错,Handler也是很不错的,但是考虑一种情况,当还在网络请求的时候,应用突然结束怎么办,那这样岂不是要造成内存泄漏。而RxJava就可以很好的处理这个问题,那他是怎么做的呢,就是RxJava其实有两种对象在里面,就是大家所说的被观察者和观察者,两者之间是通过订阅产生联系,这个时候只要我们在应用结束的时候取消订阅,那么这个问题就解决了。
好话不多说,那怎么才能利用这种框架完成网络请求以及更加简洁的刷新界面呢?
依赖如下:
/**
* RxJava*/
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.2'
/**
* Retrofit
* */
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.google.code.gson:gson:2.8.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
/**
* Okhttp*/
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
implementation "com.squareup.okhttp3:logging-interceptor:3.8.0"
1.首先我们先做初始化
private static final int DEFAULT_TIME_OUT=5;//超时时间
private static final int DEFAULT_READ_OUT=10;//读超时时间
private RetrofitmRetrofit=null;
private static RetrofitServiceManagermRetrofitServiceManager=null;
//构造方法中去初始化Retrifit和Okhttp
private RetrofitServiceManager(){
OkHttpClient.Builder builder=new OkHttpClient.Builder();
HttpLoggingInterceptor httpLoggingInterceptor=new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
builder.addInterceptor(httpLoggingInterceptor);
builder.connectTimeout(DEFAULT_TIME_OUT, java.util.concurrent.TimeUnit.SECONDS);
builder.readTimeout(DEFAULT_READ_OUT, java.util.concurrent.TimeUnit.SECONDS);
//添加公共参数拦截器
// HttpCommonInterceptor httpCommonInterceptor;
//初始化Retrofit对象
mRetrofit=new Retrofit.Builder()
.client(builder.build())//Okhttp对象
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Constant.Base_url)
.build();
}
//获取实例
public static RetrofitServiceManagergetInstance(){
if(mRetrofitServiceManager==null)
return new RetrofitServiceManager();
return mRetrofitServiceManager;
}
/**用于生成接口实例*/
public T create(Class service){
return mRetrofit.create(service);
}
说明
初始化Okhttp和Retrofit,Retrofit支持RxJava2响应式的请求操作。create方法用生成service层的接口实例。那好我们接下来简单看看service层
public interface Service {
//行使网络请求并返回,观察者对象中只能含有MovieSubject的数据元素
@GET("api/data/福利/10/{pageNum}")
Observable<BaseResp<List<PhotoItem>>> getPhotoDate(@Path("pageNum")int pageNum);//转化为被观察者,本来调用的时call方法
@FormUrlEncoded
@POST("news/list")
Call<String> getWeather(@Field("cityId") String cityId, @Field("key") String key);
//r Subscription subscription
}
说明
通过注解的方式配置接口,我想这里面的详细操作,官方文档上面都有解释。
因为我们的可以看到我们的数据模型是带有泛型的,getPhoto的返回值Observable<BaseResp<List<PhotoItem>>>这主要根据服务器的返回的数据格式而定,通过这个模型我们不难看出,这个返回的数据模型中至少有一个列表。
BaseResp.java
public boolean error;
public T results;
@Override
public String toString() {
return "BaseResp{" +
"error=" + error +
", results=" + results +
'}';
}
PhotoItem.java
private String _id;
private String createdAt;
private String desc;
private String publishedAt;
private String source;
private String type;
private String url;
private boolean used;
private String who;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isUsed() {
return used;
}
public void setUsed(boolean used) {
this.used = used;
}
public String getWho() {
return who;
}
public void setWho(String who) {
this.who = who;
}
@Override
public String toString() {
return "PhotoItem{" +
"_id='" + _id + '\'' +
", createdAt='" + createdAt + '\'' +
", desc='" + desc + '\'' +
", publishedAt='" + publishedAt + '\'' +
", source='" + source + '\'' +
", type='" + type + '\'' +
", url='" + url + '\'' +
", used=" + used +
", who='" + who + '\'' +
'}';
}
3.实现请求业务
public class NetRepository {
public Observable<BaseResp<List<PhotoItem>>> getPhotoData(int page){
return RetrofitServiceManager.getInstance()
.create(Service.class)
.getPhotoDate(page)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io());
}
}
可以看出观察者是在主线程,被观察者在io线程上
4.任务调度
netRepository.getPhotoData(1)
.subscribe(new Observer<BaseResp<List<PhotoItem>>>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(BaseResp<List<PhotoItem>> listBaseResp) {
Log.d(TAG, "onNext: "+listBaseResp);
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: "+e.getMessage() );
}
@Override
public void onComplete() {
}
});
注意当应用结束时我们可以这么写,防止内存泄露:
@Override
protected void onDestroy() {
super.onDestroy();
if (compositeDisposable != null && !compositeDisposable.isDisposed()){
compositeDisposable.dispose();
}
}
最后。查看结果:
07-04 16:37:28.750 15741-15741/com.example.wydnn.frame D/MainActivity>: onNext: BaseResp{error=false, results=[PhotoItem{_id='5b3ae394421aa906e7db029b', createdAt='2018-07-03T10:46:44.112Z', desc='2018-07-03', publishedAt='2018-07-03T00:00:00.0Z', source='web', type='福利', url='http://ww1.sinaimg.cn/large/0065oQSqly1fswhaqvnobj30sg14hka0.jpg', used=true, who='lijinshanmx'}
网友评论