RxRetroHttp为多套API请求适配而生

前言

"后端更新换代,新接口返回全用新的规则,老接口不变!"。。。WTF!

“我们的这几个网站,要做一个统一的App,后端都是现成的,这是API文档。”。。。几个网站的API规范和请求Host地址居然完全不一样?。。。WTF!

。。。千万只草泥马呼啸而过。。。实时切换BaseUrl?Retrofit注解全加上@Url?。。。无奈。。。

虽然说现在已经有很多Http请求框架了,也有很多针对RxJava+Retrofit的二次封装,其中也不乏很多动态替换BaseUrl的框架。但是如果需要更好的处理除了BaseUrl之外需求,比如针对各套API规则,不同的拦截处理、不同的返回异常逻辑处理等等,大多没有给予解决方案。因此,RxRetroHttp应运而生。

总览

我们先来看看,RxRetroHttp是通过什么方式处理这种情况的。

初始化

首先,大多库的必备阶段:初始化。我们先来看看初始化的代码,在Application的onCreate中执行

RxRetroHttp.init(this)
      .setBaseUrl("http://api1.com/")
      .setApiResultClass(Api1Result.class)
      .generateRetroClient()

这样,初始化就做完了。。。此处应有掌声。。。

“我掌你大爷!!!说好的处理多套API规则呢!!!”

额咳。。。客观莫急。。。待我徐徐道来

通过刚刚的初始化,你已经设置了App中主API请求的基本配置。如果你的App中,就像前言里描述的那样,需要对接多套API规则,那么在初始化之后,再加入如下代码

RxRetroHttp.getInstance()
      .setBaseUrl("https://api2.com/")
      .setApiResultClass(Api2Result.class)
      .generateRetroClient("API2")

相信大家已经看出区别了吧,没错,就是在generateRetroClient这个方法中,加入了一个Tag,而这个Tag,就是处理多套API请求的关键。

在setApiResultClass方法中,传入的就是对于API规范的基类,具体情况会在后面讲到。

调用

初始化完成后,如何调用呢

RxRetroHttp.create(Api2Service.class).getApi2Info()

我们可以看到,这就是Retrofit风格的调用方式。

在这里,Api2Service也就是Retrofit风格的ApiService,但是也略有不同

@RetroTag("API2")
public interface Api2Service {
  @GET("test/info")
  Observable<Api2Info> getApi2Info();
}

我们看看不同在哪,下面是纯Retrofit的书写方式

public interface Api2Service {
  @GET("test/info")
  Observable<Api2Result<Api2Info>> getApi2Info();
}

没错,区别就在于:

1、省去了基类的这一层包裹。这么做的原因是,个人认为,在ApiService这一层,每个接口定义都需要设置ApiResult包裹是不人性的,哈哈哈。

2、RetroTag接口,用于指示Tag,当然这是对于初始化时设置了Tag的API请求。

当然,如果你还是希望以基类包裹的方式,也是可以的,那就是在初始化的时候,不调用setApiResultClass方法就行了。

另外,如果你不想增加RetroTag注解,也是可以的,那在调用的时候,就需要调用另一个方法,放入Tag,如下:

RxRetroHttp.create(Api2Service.class, "API2").getApi2Info()

ApiResult

现在,我们来看看ApiResult。

在setApiResultClass方法中传入的,是实现了IApiResult接口的请求返回基类,简单的样例代码如下

public class Api2Result<T> implements IApiResult<T> {
  private int code;
  private String msg;
  private T result;
  @Override
  public boolean isSuccess(){
    return code == 1;
  }
  @Override
  public T getData(){
    return result;
  }
  @Override
  public String getResultMsg(){
    return msg;
  }
  @Override
  public String getResultCode(){
    return String.valueOf(code);
  }
  @Override
  public String getDataField(){
    return "result";
  }
}

其对应的返回json如下

{
  code: 1,
  msg: "请求成功",
  result: {
    ...
  }
}

这是一个较为常用的API返回格式,而我们所要做的,就是实现几个基本方法,其中,isSuccess()返回的是请求成功的判断,getData()返回的是请求到的具体数据,getResultMsg()返回的是API请求信息,getResultCode()表示返回码,getDataField()返回的是json数据中表示具体数据的字段(在上面的json例子中,就是“result”)。

更多配置

Http请求不可能没有相关的配置,而本框架并没有为大家内置很多配置方法,原因是,我认为这并不是本框架的主要功能。当然,大家也是可以进行自定义配置的,配置方式如下:

RxRetroHttp.init(this).setXXX().setXXX();
Retrofit.Builder retrofitBuilder = RxRetroHttp.getRetrofitBuilder();
retrofitBuilder.setXXX().setXXX();
OkHttpClient.Builder okHttpBuilder = RxRetroHttp.getOkHttpClientBuilder();
okHttpBuilder.setXXX().setXXX();
RxRetroHttp.getInstance().generateRetroClient();
//RxRetroHttp.getInstance().generateRetroClient("YourTag")

当然各套API请求之间的配置也是隔离的。框架也提供了一些简单的快捷配置方法,比如addInterceptor、addNetworkInterceptor等,更多的配置可以通过上述方式,获取retrofitBuilder和okHttpBuilder来配置。

通过Tag的方式或许不是最好的方式,我也会继续尝试其他的方式,以对比便利性,如果大家有更好的方案提议,也希望能够留言告诉我,感谢大家。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • Android可自定义神奇动效的卡片切换视图实例

    前言 面对众多卡片层叠效果,我们的产品童鞋也突发奇想,搞出了另一种卡片层叠切换展示的交互,而且产品狗们居然要求多做几种动效给他们看,好让他们选择,这简直就是要搞事情啊,what are you 弄啥咧?! "哥哥我做不到啊.....啊.....呸",做为一名有节操的程序猿,自然是不能说出这么没有出息的话,哥就满足你们,于是,出了个可自定义动效的卡片切换视图,效果如下所示 思路 首先,要展示出卡片层叠的视觉效果.在这里,我们通过方块的缩放大小差异以及在Y方向上的位置差异,来展现这种视觉效

  • Android亮屏速度分析总结

    前面聊的 最近在调试项目的亮屏速度,我们希望在按下power键后到亮屏这个时间能达到500MS以内,在Rockchip 3399和3288上面的时间都不能达到要求,因此引发了一系列的调试之路. 计算按下power键到亮屏的时间 Android 唤醒时间统计 刚开始的时候,我只在android阶段统计时间,也能看到时间的差异,但是不是最准确的,我统计的时间日志如下 01-18 09:13:40.992 683 772 D SurfaceControl: Excessive delay in set

  • Android四大组件之Service详解

    一.Service简介 Service是Android程序中四大基础组件之一,它和Activity一样都是Context的子类,只不过它没有UI界面,是在后台运行的组件. Service是Android中实现程序后台运行的解决方案,它非常适用于去执行那些不需要和用户交互而且还要求长期运行的任务.Service默认并不会运行在子线程中,它也不运行在一个独立的进程中,它同样执行在UI线程中,因此,不要在Service中执行耗时的操作,除非你在Service中创建了子线程来完成耗时操作. 二.Serv

  • Android添加音频的几种方法

    在res文件夹中新建一个文件夹,命名为raw.在里面放入我们需要的音频文件. 第一种: // 根据资源创建播放器对象 player = MediaPlayer.create(this, R.raw.xiaoxiaole); try { player.prepare();// 同步 } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOExcept

  • Android启动优化之延时加载的步骤详解

    前言 在应用启动的时候,为了加快启动速度,往往需要把一些比较重的操作放到子线程中,或者是延时加载.将任务放在子线程中是一个比较简单并且看起来有效的操作,但是呢,也不能太过于依赖子线程,它虽然不会阻塞主线程,但是却会跟主线程抢占CPU,当子线程很多并且任务很重的时候,也还是会拖慢主线程的,不信你可以打出Systrace看一下.延时加载也是一个比较好的策略,但难点就在于延时多久,这个时间并不好掌控. 下面话不多说了,来一起看看详细的介绍吧 IdleHandler 以前一直在想Android为什么不在

  • Android四大组件之Activity详解

    一.Activity的生命周期 首先,我们来了解一下Activity典型的生命周期 一个Activity从启动到结束会以如下顺序经历整个生命周期: onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory().包含了六个部分,还有一个onRestart()没有调用, 下面就来一一介绍 onCreate():当 Activity 第一次创建时会被调用.当 Activity 第一次创建时会被调用.这是生命周

  • Android实现图片在屏幕内缩放和移动效果

    通常我们遇到的图片缩放需求,都是图片基于屏幕自适应后,进行缩放和移动,且图片最小只能是自适应的大小.最近遇到一个需求,要求图片只能在屏幕内缩放和移动,不能超出屏幕. 一.需求 在屏幕中加载一张图片,图片可以手势缩放移动.但是图片最大只能缩放到屏幕大小,也只允许在屏幕内移动.可以从系统中读取图片(通过绝对路径),也可以从资源文件中读取图片. 二.自定义ZoomImageView 屏幕内手势缩放图片与普通的图片缩放相比,比较麻烦的是,需要计算图片的精确位置.不同于普通缩放的图片充满屏幕,屏内缩放的图

  • Android线程中Handle的使用讲解

    Android UI线程是不安全的,子线程中进行UI操作,可能会导致程序的崩溃,解决办法:创建一个Message对象,然后借助Handler发送出去,之后在Handler的handleMessage()方法中获得刚才发送的Message对象,然后在这里进行UI操作就不会再出现崩溃了 定义类继承Handler public class BallHandler extends Handler{ ImageView imageview; Bitmap bitmap; public BallHandle

  • Android传感器SensorEventListener之加速度传感器

    这个类(我的是Activity中)继承SensorEventListener接口 先获取传感器对象,再获取传感器对象的类型 //获取传感器管理对象 SensorManager mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); // 获取传感器的类型(TYPE_ACCELEROMETER:加速度传感器) Sensor mSensor = mSensorManager.getDefaultSensor(

  • Android四大组件之BroadcastReceiver详解

    BroadcastReceiver(广播接收器),在Android开发中,BroadcastReceiver的应用场景非常多,属于Android四大组件之一. Android 广播分为两个角色:广播发送者.广播接收者 一. 作用 用于监听 / 接收 应用发出的广播消息,并做出响应 应用场景: 不同组件之间通信(包括应用内 / 不同应用之间) 与 Android 系统在特定情况下的通信(如当电话呼入时.网络可用时) 多线程通信 二.实现原理 Android中的广播使用了设计模式中的观察者模式:基于

随机推荐