详解RxJava2 Retrofit2 网络框架简洁轻便封装

网友投稿 609 2023-03-07


详解RxJava2 Retrofit2 网络框架简洁轻便封装

前言

Rxjava2、Retrofit2火了有一段时间了,前段时间给公司的项目引入了这方面相关的技术,在此记录一下相关封装的思路。

需求

封装之前要先明白需要满足哪些需求。

RxJava2衔接Retrofit2

Retrofit2网络框架异常的统一处理

兼容fastjson(可选)

RxJava2内存泄漏的处理

异步请求加入Loading Dialog

依赖

implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

implementation 'io.reactivex.rxjava2:rxjava:2.1.3'

implementation 'com.squareup.retrofit2:retrofit:2.3.0'

implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

implementation 'com.squareup.okhttp3:okhttp:3.9.0'

implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.0'

implementation 'com.alibaba:fastjson:1.1.59.android'//可选其它框架比如Gson

RxJava2衔接Retrofit2

先封装一个网络框架的管理类,方便调用

public class RxHttp {

private final String BASE_URL = "https://github.com/";

private Map mRetrofitMap = new HashMap<>();

private RxHttp() {

}

/**

* 单例模式

* @return

*/

public static RxHttp getInstance() {

return RxHttpHolder.sInstance;

}

private static class RxHttpHolder{

private final static RxHttp sInstance = new RxHttp();

}

public Retrofit getRetrofit(String serverUrl) {

Retrofit retrofit;

if (mRetrofitMap.containsKey(serverUrl)) {

retrofit = mRetrofitMap.get(serverUrl);

} else {

retrofit = createRetrofit(serverUrl);

mRetrofitMap.put(serverUrl, retrofit);

}

return retrofit;

}

public SyncServerService getSyncServer(){

return getRetrofit(BASE_URL).create(SyncServerService.class);

}

/**

*

* @param baseUrl baseUrl要以/作为结尾 eg:https://github.com/

* @return

*/

private Retrofit createRetrofit(String baseUrl) {

OkHttpClient client = new OkHttpClient().newBuilder()

.readTimeout(30, TimeUnit.SECONDS)

.connectTimeout(30, TimeUnit.SECONDS)

.retryOnConnectionFailure(true)

.build();

return new Retrofit.Builder()

.baseUrl(baseUrl)

.addConverterFactory(FastJsonConverterFactory.create())

.addCallAdapterFactory(RxJava2CallAdapterFactory.create())

.client(client)

.build();

}

}

Restful风格接口

public interface SyncServerService {

@GET("service/mobile/IsLatestVersion.ashx")

Observable> getLatestVersion(@Query("SoftwareID") String SoftwareID,

@Query("ClientVersion") String ClientVersion);

}

服务端返回的基本类型,在导入类的时候特别需要注意区分该Response类型

public class Response {

public int ret;//约定 -1为server返回数据异常 200为正常范围

public String msg;

public T data;

public int getRet() {

return ret;

}

public void setRet(int ret) {

this.ret = ret;

}

public String getMsg() {

return msg;

}

public void setMsg(String msg) {

this.msg = msg;

}

public T getData() {

return data;

}

public void setData(T data) {

this.data = data;

}

}

fastjson的支持

由于项目中采用了fastjson,square尚未实现对fastjson的支持,但是保留了代码的扩展,这边可以自己封装一下fastjson的转换器。

public class FastJsonConverterFactory extends Converter.Factory {

private final SerializeConfig mSerializeConfig;

private FastJsonConverterFactory(SerializeConfig serializeConfig) {

this.mSeriaiigKqgBhzlizeConfig = serializeConfig;

}

public static FastJsonConverterFactory create() {

return create(Serialhttp://izeConfig.getGlobalInstance());

}

public static FastJsonConverterFactory create(SerializeConfig serializeConfig) {

return new FastJsonConverterFactory(serializeConfig);

}

@Override

public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {

return new FastJsonRequestBodyConverter<>(mSerializeConfig);

}

@Override

public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {

return new FastJsonResponseBodyConvert<>(type);

}

}

final class FastJsonRequestBodyConverter implements Converter {

private final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");

private SerializeConfig mSerializeConfig;

public FastJsonRequestBodyConverter(SerializeConfig serializeConfig) {

this.mSerializeConfig = serializeConfig;

}

@Override

public RequestBody convert(T value) throws IOException {

return RequestBody.create(MEDIA_TYPE, JSON.toJSONBytes(value, mSerializeConfig));

}

}

final class FastJsonResponseBodyConvert implements Converter {

private Type mType;

public FastJsonResponseBodyConvert(Type type) {

this.mType = type;

}

@Override

public T convert(ResponseBody value) throws IOException {

return JSON.parseObject(value.string(), mType);

}

}

数据返回统一处理

public abstract class BaseObserver implements Observer> {

@Override

public final void onNext(@NonNull Response result) {

if (result.getRet() == -1) {

onFailure(new Exception(result.getMsg()), result.getMsg());//该异常可以汇报服务端

} else {

onSuccess(result.getData());

}

}

@Override

public void onError(@NonNull Throwable e) {

onFailure(e, RxExceptionUtil.exceptionHandler(e));

}

@Override

public void onComplete() {

}

@Override

public void onSubscribe(@NonNull Disposable d) {

}

public abstract void onSuccess(T result);

public abstract void onFailure(Throwable e, String errorMsg);

}

下面加入了异常处理类

public class RxExceptionUtil {

public static String exceptionHandler(Throwable e){

String errorMsg = "未知错误";

if (e instanceof UnknownHostException) {

errorMsg = "网络不可用";

} else if (e instanceof SocketTimeoutException) {

errorMsg = "请求网络超时";

} else if (e instanceof HttpException) {

HttpException httpException = (HttpException) e;

errorMsg = convertStatusCode(httpException);

} else if (e instanceof ParseException || e instanceof JSONException

|| e instanceof com.alibaba.fastjson.JSONException) {

errorMsg = "数据解析错误";

}

return errorMsg;

}

private static String convertStatusCode(HttpException httpException) {

String msg;

if (httpException.code() >= 500 && httpException.code() < 600) {

msg = "服务器处理请求出错";

} else if (httpException.code() >= 400 && httpException.code() < 500) {

msg = "服务器无法处理请求";

} else if (httpException.code() >= 300 && httpException.code() < 400) {

msg = "请求被重定向到其他页面";

} else {

msg = httpException.message();

}

return msg;

}

}

异步请求加入Loading Dialog

这个时候我们可以根据自己项目中统一封装的dialog自行扩展BaseObserver

public abstract class ProgressObserver extends BaseObserver{

private MaterialDialog mMaterialDialog;

private Context mContext;

private String mLoadingText;

public ProgressObserver(Context context){

this(context, null);

}

public ProgressObserver(Context context, String loadingText){

mContext = context;

mLoadingText = loadingText;

}

@Override

public void onSubscribe(@NonNull Disposable d) {

if (!d.isDisposed()) {

mMaterialDialog = new MaterialDialog.Builder(mContext).content(mLoadingText == null ? "正在加载中..."

: mLoadingText).isProgress(true).build();

mMaterialDialog.show();

}

}

@Override

public void onComplete() {

if (mMaterialDialog != null) {

mMaterialDialog.dismiss();

}

}

@Override

public void onError(@NonNull Throwable e) {

super.onError(e);

if (mMaterialDialog != null) {

mMaterialDialog.dismiss();

}

}

}

加入调度类,方便调用线程切换和解决内存泄漏的问题

public class RxSchedulers {

public static ObservableTransformer observableIO2Main(final Context context) {

return upstream -> {

Observable observable = upstream.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread());

return composeContext(context, observable);

};

}

public static ObservableTransformer observableIO2Main(final RxFragment fragment) {

return upstream -> upstream.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread()).compose(fragment.bindToLifecycle());

}

private static ObservableSource composeContext(Context context, Observable observable) {

if(context instanceof RxActivity) {

return observable.compose(((RxActivity) context).bindUntilEvent(ActivityEvent.DESTROY));

} else if(context instanceof RxFragmentActivity){

return observable.compose(((RxFragmentActivity) context).bindUntilEvent(ActivityEvent.DESTROY));

}else if(context instanceof RxAppCompatActivity){

return observable.compose(((RxAppCompatActivity) context).bindUntilEvent(ActivityEvent.DESTROY));

}else {

return observable;

}

}

}

讲了那么多,那么如何使用这个封装呢?下面来看下如何使用。

RxHttp.getInstance().getSyncServer().getLatestVersion("1", "1.0.0")

.compose(RxSchedulers.observableIO2Main(this))

.subscribe(new ProgressObserver(this) {

@Override

public void onSuccess(String result) {

Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();

}

@Override

public void onFailure(Throwable e, String errorMsg) {

}

});


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

上一篇:安卓开发接口(安卓开发接口回调)
下一篇:微信小程序实现打开内置地图功能【附源码下载】
相关文章

 发表评论

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