深入浅出RxJava+Retrofit+OkHttp网络请求

网友投稿 398 2023-03-15


深入浅出RxJava+Retrofit+OkHttp网络请求

浅谈Rxjava+Retrofit+OkHttp 封装使用 之前发出后收到很多朋友的关注,原本只是自己学习后的一些经验总结,但是有同学运用到实战当中,这让我很惶恐,所有后续一直更新了很多次版本,有些地方难免有所变动导致之前的博客有所出入,正好最近受到掘金邀请内测博客,所以决定重新写一版,按照最后迭代完成的封装详细的讲述一遍,欢迎大家关注!

注意:由于本章的特殊性,后续文章比较长而且复杂,涉及内容也很多,所以大家准备好茶水,前方高能预警。

简介:

Retrofit: Retrofit是Square 公司开发的一款正对android 网络请求的框架。底层基于OkHttp 实现,OkHttp 已经得到了google 官方的认可。

OkHttp: 也是Square 开源的网络请求库

RxJava:RxJava 在 github 主页上的自我介绍是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,概括得非常精准。总之就是让异步操作变得非常简单。

各自的职责:Retrofit 负责请求的数据和请求的结果,使用接口的方式呈现,OkHttp 负责请求的过程,RxJava 负责异步,各种线程之间的切换。

RxJava + Retrofit + okHttp 已成为当前Android 网络请求最流行的方式。

封装成果

封装完以后,具有如下功能:

1.Retrofit+Rxjava+okhttp基本使用方法

    2.统一处理请求数据格式

    3.统一的ProgressDialog和回调Subscriber处理

    4.取消http请求

    5.预处理http请求

    6.返回数据的统一判断

    7.失败后的retry封装处理

    8.RxLifecycle管理生命周期,防止泄露

实现效果:

具体使用

封装后http请求代码如下

// 完美封装简化版

private void simpleDo() {

SubjectPost postEntity = new SubjectPost(simpleOnNextListener,this);

postEntity.setAll(true);

HttpManager manager = HttpManager.getInstance();

manager.doHttpDeal(postEntity);

}

// 回调一一对应

HttpOnNextListener simpleOnNextListener = new HttpOnNextListener>() {

@Override

public void onNext(List subjects) {

tvMsg.setText("已封装:\n" + subjects.toString());

}

/*用户主动调用,默认是不需要覆写该方法*/

@Override

public void onError(Throwable e) {

super.onError(e);

tvMsg.setText("失败:\n" + e.toString());

}

};

是不是很简单?你可能说这还简单,好咱们对比一下正常使用Retrofit的方法

/**

* Retrofit加入rxjava实现http请求

*/

private void onButton9Click() {

//手动创建一个OkHttpClient并设置超时时间

okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder();

builder.connectTimeout(5, TimeUnit.SECONDS);

Retrofit retrofit = new Retrofit.Builder()

.client(builder.build())

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.baseUrl(HttpManager.BASE_URL)

.build();

/ 加载框

final ProgressDialog pd = new ProgressDialog(this);

HttpService apiService = retrofit.create(HttpService.class);

Observable observable = apiService.getAllVedioBy(true);

observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

.subscribe(

new Subscriber() {

@Override

public void onCompleted() {

if (pd != null && pd.isShowing()) {

pd.dismiss();

}

}

@Override

public void onError(Throwable e) {

if (pd != null && pd.isShowing()) {

pd.dismiss();

}

}

@Override

publichttp:// void onNext(RetrofitEntity retrofitEntity) {

tvMsg.setText("无封装:\n" + retrofitEntity.getData().toString());

}

@Override

public void onStart() {

super.onStart();

pd.show();

}

}

);

}

可能你发现确是代码有点多,但是更加可怕的是,如果你一个activity或者fragment中多次需要http请求,你需要多次重复的写回调处理(一个回到就有4个方法呀!!!!反正我是忍受不了),而且以上处理还没有做过多的判断和错误校验就如此复杂!~好了介绍完了,开始咱们的优化之路吧!

项目结构:

Retrofit

咱家今天的主角来了,咱们也深入浅出一下了解下Retrofit使用,前方高能,如果你是深度Retrofit选手请直接跳过本节!!!

1.首先确保在AndroidManifest.xml中请求了网络权限

2.在app/build.gradle添加引用

/*rx-android-java*/

compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

compile 'com.trello:rxlifecycle:1.0'

compile 'com.trello:rxlifecycle-components:1.0'

/*rotrofit*/

compile 'com.squareup.retrofit2:retrofit:2.1.0'

compile 'com.squareup.retrofit2:converter-gson:2.0.0'

compile 'com.google.code.gson:gson:2.8.0'

3.常用注解

这里介绍一些常用的注解的使用

@Query、@QueryMap:用于Http Get请求传递参数

@Field:用于Post方式传递参数,需要在请求接口方法上添加@FormUrlEncoded,即以表单的方式传递参数

@Body:用于Post,根据转换方式将实例对象转化为对应字符串传递参数.比如Retrofit添加GsonConverterFactory则是将body转化为gson字符串进行传递

@Path:用于URL上占位符

@Part:配合@Multipart使用,一般用于文件上传

@Header:添加http header

@Headers:跟@Header作用一样,只是使用方式不一样,@Header是作为请求方法的参数传入,@Headers是以固定方式直接添加到请求方法上

ReTrofit基本使用:

首先给定一个测试接口文档,后面的博客中我们都是用这个接口调试

/**

* @api videoLink 50音图视频链接

* @url http://izaodao.com/Api/AppFiftyToneGraph/videoLink

* @method post

* @param once_no bool(选填,ture无链接) 一次性获取下载地址

* @return json array(

* ret:1成功,2失败

* msg:信息

* data:{

* name:视频名称

* title:标题

* }

)

1.初始化retrofit

要向一个api发送我们的网络请求 ,我们需要使用Retrofit builder类并指定service的base URL(通常情况下就是域名)。

String BASE_URL = " http://izaodao.com/Api/"

Retrofit retrofit = new Retrofit.Builder()

.baseUrl(BASE_URL)

.addConverterFactory(GsonConverterFactory.create())

.build();

2.设置接口service

注意到每个endpoint 都指定了一个关于HTTP(GET, POST, 等等。) 方法的注解以及用于分发网络调用的方法。而且这些方法的参数也可以有特殊的注解。

/**

* 接口地址

* Created by WZG on 2016/7/16.

*/

public interface MyApiEndpointInterface {

@POST("AppFiftyToneGraph/videoLink")

Call getAllVedio(@Body boolean once_no)

}

3.得到call然后同步处理处理回调:

MyApiEndpointInterface apiService = retrofit.create(MyApiEndpointInterface.class);

Call call = apiService.getAllVedio(true);

call.enqueue(new Callback() {

@Override

public void onResponse(Response response, Retrofit retrofit) {

RetrofitEntity entity = response.body();

Log.i("tag", "onResponse----->" + entity.getMsg());

}

@Override

public void onFailure(Throwable t) {

Log.i("tag", "onFailure----->" + t.toString());

}

});

这就是简单的Retrofit使用步骤,接下来我们结合RxJava讲述

ReTrofit+Rxjava基本使用

对比之前的Retrofit使用

1.在于我们需要修改service接口返回信息我们需要返回一个Observable对象

@POST("AppFiftyToneGraph/videoLink")

Observable getAllVedioBy(@Body boolean once_no);

2.然后初始化Retrofit需要添加对Rxjava的适配,注意一定要retrofit2才有这个功能哦

Retrofit retrofit = new Retrofit.Builder()

.client(builder.build())

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.baseUrl(HttpManager.BASE_URL)

.build();

3.回调通过RxJava处理

HttpService apiService = retrofit.create(HttpService.class);

Observable observable = apiService.getAllVedioBy(true);

observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

.subscribe(

new Subscriber() {

@Override

public void onCompleted() {

}

@Override

public void onError(Throwable e) {

}

@Override

public void onNext(RetrofitEntity retrofitEntity) {

tvMsg.setText("无封装:\n" + retrofitEntity.getData().toString());

}

}

);

简单的RxJava集合Retrofit的使用就介绍完了,同样的可以发现使用起来很多重复性的代码,而且使用也不是那么简单,所以才有了下面的封装

ReTrofit+Rxjava进阶封装之路

先来一张流程图压压惊

请求数据封装

1.参数

首先需要封装的使我们的数据类,在数据类中需要封装请求中用到的相关数据的设置,比如请求参数、方法、加载框显示设置等等

public abstract class BaseApi implements Func1, T> {

//rx生命周期管理

private SoftReference rxAppCompatActivity;

/*回调*/

private SoftReference listener;

/*是否能取消加载框*/

private boolean cancel;

/*是否显示加载框*/

private boolean showProgress;

/*是否需要缓存处理*/

private boolean cache;

/*基础url*/

private String baseUrl="http://izaodao.com/Api/";

/*方法-如果需要缓存必须设置这个参数;不需要不用設置*/

private String mothed;

/*超时时间-默认6秒*/

private int connectionTime = 6;

/*有网情况下的本地缓存时间默认60秒*/

private int cookieNetWorkTime=60;

/*无网络的情况下本地缓存时间默认30天*/

private int cookieNoNetWorkTime=24*60*60*30;

}

注释很详细,这里不具体描述了,由于这里是最后封装完成以后的代码,所以有些内容本章还会部分不会涉及,因为功能太多,还是按照一开始的博客章节讲解。

2.抽象api接口

/**

* 设置参数

*

* @param retrofit

* @return

*/

public abstract Observable getObservable(Retrofit retrofit);

通过子类也即是我们的具体api接口,通过getObservable实现service中定义的接口方法,例如:

public class SubjectPostApi extends BaseApi {

xxxxxxx

xxxxxxx

@Override

public Observable getObservable(Retrofit retrofit) {

HttpPostService service = retrofit.create(HttpPostService.class);

return service.getAllVedioBys(isAll());

}

}

通过传入的Retrofit对象,可以随意切换挑选Service对象,得到定义的注解方法,初始完成以后返回Observable对象。

3.结果判断

这里结合RxJava的map方法在服务器返回数据中,统一处理数据处理,所以BaseApi implements

Func1, T>,后边结合结果处理链接起来使用

@Override

public T call(BaseResultEntity httpResult) {

if (httpResult.getRet() == 0) {

throw new HttpTimeException(httpResult.getMsg());

}

return httpResult.getData();

}

由于测试接口,也是当前我们公司接口都是有统一规则的,想必大家都有这样的接口规则,所以才有这里的统一判断,规则如下:

* ret:1成功,2失败

* msg:信息

* data:{

* name:视频名称

* title:标题

* }

其实上面的接口文档中就介绍了,统一先通过ret判断,失败显示msg信息,data是成功后的数据也就是用户关心的数据,所以可封装一个结果对象BaseResultEntity.

4.结果数据

/**

* 回调信息统一封装类

* Created by WZG on 2016/7/16.

*/

public class BaseResultEntity {

// 判断标示

private int ret;

// 提示信息

private String msg;

//显示数据(用户需要关心的数据)

private T data;

xxxxx get-set xxxxx

}

这里结合BaseApi的Func1判断,失败直接抛出一个异常,交个RxJava的onError处理,成功则将用户关心的数据传给Gson解析返回

5.泛型传递

BaseResultEntity中的泛型T也就是我们所关心的回调数据,同样也是Gson最后解析返回的数据,传递的过程根节点是通过定义service方法是给定的,例如:

public interface HttpPostService {

@POST("AppFiftyToneGraph/videoLink")

Call getAllVedio(@Body boolean once_no);

}

其中的RetrofitEntity就是用户关心的数据类,通过泛型传递给最后的接口。

6.强调

很多兄弟通过QQ群反馈给我说,使用一个接口需要写一个对应的api类继承BaseApi是不是很麻烦,我这里强调一下,这样封装是为了将一个Api接口作为一个对象去封装,个人觉得有必要封装成一个类,在日后工程日益增加接口随着增加的同时,对象的做法更加有利于查找接口和修改接口有利于迭代。

操作类封装

1初始对象

首先初始化一个单利方便HttpManager请求;这里用了volatile的对象

private volatile static HttpManager INSTANCE;

//构造方法私有

private HttpManager() {

}

//获取单例

public static HttpManager getInstance() {

if (INSTANCE == null) {

synchronized (HttpManager.class) {

if (INSTANCE == null) {

INSTANCE = new HttpManager();

}

}

}

return INSTANCE;

}

2接口处理和回调处理:

/**

* 处理http请求

*

* @param basePar 封装的请求数据

*/

public void doHttpDeal(BaseApi basePar) {

//手动创建一个OkHttpClient并设置超时时间缓存等设置

OkHttpClient.Builder builder = new OkHttpClient.Builder();

builder.connectTimeout(basePar.getConnectionTime(), TimeUnit.SECONDS);

builder.addInterceptor(new CookieInterceptor(basePar.isCache()));

/*创建retrofit对象*/

Retrofit retrofit = new Retrofit.Builder()

.client(builder.build())

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.baseUrl(basePar.getBaseUrl())

.build();

/*rx处理*/

ProgressSubscriber subscriber = new ProgressSubscriber(basePar);

Observable observable = basePar.getObservable(retrofit)

/*失败后的retry配置*/

.retryWhen(new RetryWhenNetworkException())

/*生命周期管理*/

.compose(basePar.getRxAppCompatActivity().bindToLifecycle())

/*http请求线程*/

.subscribeOn(Schedulers.io())

.unsubscribeOn(Schedulers.io())

/*回调线程*/

.observeOn(AndroidSchedulers.mainThread())

/*结果判断*/

.map(basePar);

/*数据回调*/

observable.subscribe(subscriber);

}

首先通过api接口类BaseApi的实现类中数据初始化OkHttpClient和Retrofit对象,其中包含了url,超时等,接着通过BaseApi的抽象方法getObservable得到Observable对象,得到Observable对象以后,我们就能随意的切换现成来处理,整个请求通过compose设定的rxlifecycle来管理生命周期,所以不会溢出和泄露无需任何担心,最后再服务器数据返回时,通过map判断结果,剔除错误信息,成功以后返回到自定义的ProgressSubscriber对象中,所以接下来封装ProgressSubscriber对象。

ProgressSubscriber封装

ProgressSubscriber其实是继承于Subscriber,封装的方法无非是对Subscriber的回调方法的封装

onStart():开始

onCompleted():结束

onError(Throwable e):错误

onNext(T t):成功

1.请求加载框

http请求都伴随着加载框的使用,所以这里需要在onStart()使用前初始一个加载框,这里简单的用ProgressDialog代替

/**

* 用于在Http请求开始时,自动显示一个ProgressDialog

* 在Http请求结束是,关闭ProgressDialog

* 调用者自己对请求数据进行处理

* Created by WZG on 2016/7/16.

*/

public class ProgressSubscriber extends Subscriber {

/*是否弹框*/

private boolean showPorgress = true;

/* 软引用回调接口*/

private SoftReference mSubscriberOnNextListener;

/*软引用反正内存泄露*/

private SoftReference mActivity;

/*加载框可自己定义*/

private ProgressDialog pd;

/*请求数据*/

private BaseApi api;

/**

* 构造

*

* @param api

*/

public ProgressSubscriber(BaseApi api) {

this.api = api;

this.mSubscriberOnNextListener = api.getListener();

this.mActivity = new SoftReference<>(api.getRxAppCompatActivity());

setShowPorgress(api.isShowProgress());

if (api.isShowProgress()) {

initProgressDialog(api.isCancel());

}

}

/**

* 初始化加载框

*/

private void initProgressDialog(boolean cancel) {

Context context = mActivity.get();

if (pd == null && context != null) {

pd = new ProgressDialog(context);

pd.setCancelable(cancel);

if (cancel) {

pd.setOnCancelListener(new DialogInterface.OnCancelListener() {

@Override

public void onCancel(DialogInterface dialogInterface) {

onCancelProgress();

}

});

}

UBBDCR }

}

/**

* 显示加载框

*/

private void showProgressDialog() {

if (!isShowPorgress()) return;

Context context = mActivity.get();

if (pd == null || context == null) return;

if (!pd.isShowing()) {

pd.show();

}

}

/**

* 隐藏

*/

private void dismissProgressDialog() {

if (!isShowPorgress()) return;

if (pd != null && pd.isShowing()) {

pd.dismiss();

}

}

}

由于progress的特殊性,需要指定content而且不能是Application所以这里传递一个RxAppCompatActivity,而同时上面的HttpManager同样需要,所以这里统一还是按照BaseApi传递过来,使用软引用的方式避免泄露。剩下的无非是初始化,显示和关闭方法,可以详细看代码。

2.onStart()实现

在onStart()中需要调用加载框,然后这里还有网络缓存的逻辑,后面会单独讲解,现在先忽略它的存在。

/**

* 订阅开始时调用

* 显示ProgressDialog

*/

@Override

public void onStart() {

showProgressDialog();

/*缓存并且有网*/

if (api.isCache() && AppUtil.isNetworkAvailable(RxRetrofitApp.getApplication())) {

/*获取缓存数据*/

CookieResulte cookieResulte = CookieDbUtil.getInstance().queryCookieBy(api.getUrl());

if (cookieResulte != null) {

long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000;

if (time < api.getCookieNetWorkTime()) {

if (mSubscriberOnNextListener.get() != null) {

mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte());

}

onCompleted();

unsubscribe();

}

}

}

}

3.onCompleted()实现

/**

* 完成,隐藏ProgressDialog

*/

@Override

public void onCompleted() {

dismissProgressDialog();

}

4.onError(Throwable e)实现

在onError(Throwable e)是对错误信息的处理和缓存读取的处理,后续会讲解,先忽略。

/**

* 对错误进行统一处理

* 隐藏ProgressDialog

*

* @param e

*/

@Override

public void onError(Throwable e) {

dismissProgressDialog();

/*需要緩存并且本地有缓存才返回*/

if (api.isCache()) {

Observable.just(api.getUrl()).subscribe(new Subscriber() {

@Override

public void onCompleted() {

}

@Override

public void onError(Throwable e) {

errorDo(e);

}

@Override

public void onNext(String s) {

/*获取缓存数据*/

CookieResulte cookieResulte = CookieDbUtil.getInstance().queryCookieBy(s);

if (cookieResulte == null) {

throw new HttpTimeException("网络错误");

}

long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000;

if (time < api.getCookieNoNetWorkTime()) {

if (mSubscriberOnNextListener.get() != null) {

mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte());

}

} else {

CookieDbUtil.getInstance().deleteCookie(cookieResulte);

throw new HttpTimeException("网络错误");

}

}

});

} else {

errorDo(e);

}

}

/*错误统一处理*/

private void errorDo(Throwable e) {

Context context = mActivity.get();

if (context == null) return;

if (e instanceof SocketTimeoutException) {

Toast.makeText(context, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();

} else if (e instanceof ConnectException) {

Toast.makeText(context, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();

} else {

Toast.makeText(context, "错误" + e.getMessage(), Toast.LENGTH_SHORT).show();

}

if (mSubscriberOnNextListener.get() != null) {

mSubscriberOnNextListener.get().onError(e);

}

}

5.onNext(T t)实现

/**

* 将onNext方法中的返回结果交给Activity或Fragment自己处理

*

* @param t 创建Subscriber时的泛型类型

*/

@Override

public void onNext(T t) {

if (mSubscriberOnNextListener.get() != null) {

mSubscriberOnNextListener.get().onNext(t);

}

}

主要是是将得到的结果,通过自定义的接口返回给view界面,其中的软引用对象mSubscriberOnNextListener是自定义的接口回调类HttpOnNextListener.

6.HttpOnNextListener封装

现在只需关心onNext(T t)和onError(Throwable e)接口即可,回调的触发点都是在上面的ProgressSubscriber中调用

/**

* 成功回调处理

* Created by WZG on 2016/7/16.

*/

public abstract class HttpOnNextListener {

/**

* 成功后回调方法

* @param t

*/

public abstract void onNext(T t);

/**

* 緩存回調結果

* @param string

*/

public void onCacheNext(String string){

}

/**

* 失败或者错误方法

* 主动调用,更加灵活

* @param e

*/

public void onError(Throwable e){

}

/**

* 取消回調

*/

public void onCancel(){

}

}

失败后的retry处理

这里你可能会问,Retrofit有自带的retry处理呀,的确Retrofit有自带的retry处理,但是有很多的局限,先看下使用

OkHttpClient.Builder builder = new OkHttpClient.Builder();

builder.retryOnConnectionFailure(true);

使用起来还是很方便,只需要调用一个方法即可,但是它是不可控的,也就是没有办法设置retry时间次数,所以不太灵活,既然如此还不如自己封装一下,因为用RxJava实现这个简直小菜,无形中好像已经给RxJava打了广告,中毒太深。

很简单直接上代码:

/**

* retry条件

* Created by WZG on 2016/10/17.

*/

public class RetryWhenNetworkException implements Func1, Observable>> {

// retry次数

private int count = 3;

// 延迟

private long delay = 3000;

// 叠加延迟

private long increaseDelay = 3000;

public RetryWhenNetworkException() {

}

public RetryWhenNetworkException(int count, long delay) {

this.count = count;

this.delay = delay;

}

public RetryWhenNetworkException(int count, long delay, long increaseDelay) {

this.count = count;

this.delay = delay;

this.increaseDelay = increaseDelay;

}

@Override

public Observable> call(Observable extends Throwable> observable) {

return observable

.zipWith(Observable.range(1, count + 1), new Func2() {

@Override

public Wrapper call(Throwable throwable, Integer integer) {

return new Wrapper(throwable, integer);

}

}).flatMap(new Func1>() {

@Override

public Observable> call(Wrapper wrapper) {

if ((wrapper.throwable instanceof ConnectException

|| wrapper.throwable instanceof SocketTimeoutException

|| wrapper.throwable instanceof TimeoutException)

&& wrapper.index < count + 1) { //如果超出重试次数也抛出错误,否则默认是会进入onCompleted

return Observable.timer(delay + (wrapper.index - 1) * increaseDelay, TimeUnit.MILLISECONDS);

}

return Observable.error(wrapper.throwable);

}

});

}

private class Wrapper {

private int index;

private Throwable throwable;

public Wrapper(Throwable throwable, int index) {

this.index = index;

this.throwable = throwable;

}

}

}

使用

到这里,我们第一步封装已经完成了,下面讲解下如何使用,已经看明白的各位看官,估计早就看明白了使用方式,无非是创建一个api对象继承BaseApi初始接口信息,然后调用HttpManager对象的doHttpDeal(BaseApi basePar)方法,最后静静的等待回调类HttpOnNextListener类返回的onNext(T t)成功数据或者onError(Throwable e)数据。

其实代码就是这样:

api接口对象

/**

* 测试数据

* Created by WZG on 2016/7/16.

*/

public class SubjectPostApi extends BaseApi {

// 接口需要传入的参数 可自定义不同类型

private boolean all;

/*任何你先要传递的参数*/

// String xxxxx;

/**

* 默认初始化需要给定回调和rx周期类

* 可以额外设置请求设置加载框显示,回调等(可扩展)

* @param listener

* @param rxAppCompatActivity

*/

public SubjectPostApi(HttpOnNextListener listener, RxAppCompatActivity rxAppCompatActivity) {

super(listener,rxAppCompatActivity);

setShowProgress(true);

setCancel(true);

setCache(true);

setMothed("AppFiftyToneGraph/videoLink");

setCookieNetWorkTime(60);

setCookieNoNetWorkTime(24*60*60);

}

public boolean isAll() {

return all;

}

public void setAll(boolean all) {

this.all = all;

}

@Override

public Observable getObservable(Retrofit retrofit) {

HttpPostService service = retrofit.create(HttpPostService.class);

return service.getAllVedioBys(isAll());

}

}

请求回调

// 完美封装简化版

private void simpleDo() {

SubjectPostApi postEntity = new SubjectPostApi(simpleOnNextListener,this);

postEntity.setAll(true);

HttpManager manager = HttpManager.getInstance();

manager.doHttpDeal(postEntity);

}

// 回调一一对应

HttpOnNextListener simpleOnNextListener = new HttpOnNextListener>() {

@Override

public void onNext(List subjects) {

tvMsg.setText("网络返回:\n" + subjects.toString());

}

@Override

public void onCacheNext(String cache) {

/*缓存回调*/

Gson gson=new Gson();

java.lang.reflect.Type type = new TypeToken>>() {}.getType();

BaseResultEntity resultEntity= gson.fromJson(cache, type);

tvMsg.setText("缓存返回:\n"+resultEntity.getData().toString() );

}

/*用户主动调用,默认是不需要覆写该方法*/

@Override

public void onError(Throwable e) {

super.onError(e);

tvMsg.setText("失败:\n" + e.toString());

}

/*用户主动调用,默认是不需要覆写该方法*/

@Override

public void onCancel() {

super.onCancel();

tvMsg.setText("取消請求");

}

};

后续

到这里,封装功能中很多功能还没涉及和讲解,后续会陆续更新!

先给大家看看为师的完全体功能:

1.Retrofit+Rxjava+okhttp基本使用方法

    2.统一处理请求数据格式

    3.统一的ProgressDialog和回调Subscriber处理

    4.取消http请求

    5.预处理http请求

    6.返回数据的统一判断

    7.失败后的retry处理

    8.RxLifecycle管理生命周期,防止泄露

    9.文件上传下载(支持多文件,断点续传)

    10.Cache数据持久化和数据库(greenDao)两种缓存机制

&http://nbsp;   11.异常统一处理

来个图压压惊:

源码:

RxRetrofit-终极封装-深入浅出&网络请求-GitHub

其实我还有一个兄弟版本-传送门

我不会告诉你其实我还有个更加简单的版本


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java的银行接口开发(银行项目java开发)
下一篇:Vue2.0设置全局样式(less/sass和css)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~