温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

RxJava2+Retrofit2网络框架如何封装

发布时间:2021-08-18 10:21:15 来源:亿速云 阅读:226 作者:小新 栏目:移动开发

这篇文章给大家分享的是有关RxJava2+Retrofit2网络框架如何封装的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

需求

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

  1. RxJava2衔接Retrofit2

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

  3. 兼容fastjson(可选)

  4. RxJava2内存泄漏的处理

  5. 异步请求加入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<String, Retrofit> 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<Response<String>> getLatestVersion(@Query("SoftwareID") String SoftwareID,              @Query("ClientVersion") String ClientVersion); }

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

public class Response<T> {  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.mSerializeConfig = serializeConfig;  }  public static FastJsonConverterFactory create() {   return create(SerializeConfig.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<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {   return new FastJsonResponseBodyConvert<>(type);  } }
final class FastJsonRequestBodyConverter<T> implements Converter<T, RequestBody> {  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<T> implements Converter<ResponseBody, T> {  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<T> implements Observer<Response<T>> {  @Override  public final void onNext(@NonNull Response<T> 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<T> extends BaseObserver<T>{  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 <T> ObservableTransformer<T, T> observableIO2Main(final Context context) {   return upstream -> {    Observable<T> observable = upstream.subscribeOn(Schedulers.io())      .observeOn(AndroidSchedulers.mainThread());    return composeContext(context, observable);   };  }  public static <T> ObservableTransformer<T, T> observableIO2Main(final RxFragment fragment) {   return upstream -> upstream.subscribeOn(Schedulers.io())     .observeOn(AndroidSchedulers.mainThread()).compose(fragment.<T>bindToLifecycle());  }  private static <T> ObservableSource<T> composeContext(Context context, Observable<T> 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<String>(this) {      @Override      public void onSuccess(String result) {       Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();      }      @Override      public void onFailure(Throwable e, String errorMsg) {      }     });

感谢各位的阅读!关于“RxJava2+Retrofit2网络框架如何封装”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI