项目中Rxjava +Retrofit的使用

  • 要构建项目,最先我们需要的是导入包

      com.squareup.retrofit2:retrofit:2.3.0'
      com.squareup.retrofit2:converter-gson:2.3.0
      compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0
      io.reactivex.rxjava2:rxjava:2.1.3
      io.reactivex.rxjava2:rxandroid:2.0.1
      com.squareup.okhttp3:logging-interceptor:3.8.1
    
  • 然后我们需要在Andoridmanifest中添加权限

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
      <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      <uses-permission  android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
  • 我们编写一个请求接口,例如:

       @GET("mmdb/movie/v3/list/hot.json")
       Observable<HotMovieListBean> getHostList(@Query("limit") int limit);
    
  • 我们编写一个Retrofit的网络请求类 RetrofitClient

    1.该类一共分为五部:
    - 类的构造函数,初始化Retrofit完成其基本的配置
    -
    retrofit = new Retrofit.Builder()
    .baseUrl(mBaseUrl)
    .client(okHttpClient != null?okHttpClient:new OkHttpClient())
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build();
    -返回值为Retrofit的静态方法initClient_BaseUrl,用来配置自定义的OkHttpClient

          public static RetrofitClient initClient_BaseUrl (OkHttpClient okHttpClient, @NonNull String baseUrl){
          mBaseUrl = baseUrl;
          if(mInstance == null){
          synchronized (RetrofitClient.class){
              if(mInstance == null){
                  mInstance = new RetrofitClient(okHttpClient,baseUrl);
                 }
               }
            }
               return mInstance;
          }
    
    • 获取经过实例化的Retrofit的类getInstance()

         public static RetrofitClient getInstance(){
         if(mBaseUrl == null){
         throw new RuntimeException("Please initialize Your \"BaseUrl\" in Application before use");
         }
         if(mInstance == null){
         throw new RuntimeException("Please initialize Your \"RetrofitCoreClient\" in Application before use");
         }
         return mInstance;
         }
      
    • 构建请求接口 create(Class<T> clz)

         public <T> T create(Class<T> clz){
              return retrofit.create(clz);
            } 
      
    • Api数据匹配

         public Api api(){
           return getInstance().create(Api.class);
          }
      
  • 2 值得注意的是我们在配置自定义的OkHttpClient时,需要在Application的onCreate中进行配置

  • RetrofitClient.initClient_BaseUr
    (OkHttpManager.getInstance(), Api.BASE_URL);

  • 3我们需要去编写我们自定义的OkHttpManager

  • public class OkHttpManager {
    private static OkHttpClient okHttpClient;

    public static OkHttpClient getInstance() {
    if (okHttpClient == null) {
    synchronized (OkHttpManager.class) {
    if (okHttpClient == null) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    if (BuildConfig.DEBUG) {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    builder.addInterceptor(interceptor);
    }
    GlobalParameterInterceptor globalParameterInterceptor = new GlobalParameterInterceptor();
    builder.addInterceptor(globalParameterInterceptor);
    //超时时间
    builder.connectTimeout(15, TimeUnit.SECONDS);//15S连接超时
    builder.readTimeout(20, TimeUnit.SECONDS);//20s读取超时
    builder.writeTimeout(20, TimeUnit.SECONDS);//20s写入超时
    //错误重连
    builder.retryOnConnectionFailure(true);
    okHttpClient = builder.build();
    }
    }
    }
    return okHttpClient;
    }
    }

以及

public class GlobalParameterInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
    Request oldRequest = chain.request();
    // 添加新的参数
    HttpUrl.Builder newBuilder = oldRequest.url()
            .newBuilder()
            .scheme(oldRequest.url().scheme())
            .host(oldRequest.url().host());
    Request.Builder builder = oldRequest.newBuilder()
            .method(oldRequest.method(), oldRequest.body());
    //全部添加ci请求参数,ci为所在地参数
    int ci = SPUtils.getInstance(BaseApplication.getInstance(), Constants.SP_CITY).getInt(Constants.CITY_CODE, 20);
    newBuilder.addQueryParameter("ci", String.valueOf(ci));

    // 新的请求
    Request newRequest = builder.url(newBuilder.build()).build();
    Response response = chain.proceed(newRequest);
    return response;
}
}
  • 4 在具体的项目中,我们需要去请求数据,值得注意的时我们在获取上拉刷新数据时,我们需要对这些数据进行一些特别的处理,由于我们解析得到的数据就具有两个不同的实体,但是唐门之间存在联系,所以我们我们需要先使用flatMap将两个类转换一下之间的数据类型,并返回一个Observable对象,然后在使用map方法见这个实体中我们需要使用到的数据进行转换,代码如下:

  • public Observable<List<HotMovieListBean.DataBean.HotBean>> getMoreMovieList(final int headline, final String movieIds) {
    return Observable.create(new ObservableOnSubscribe<List<HotMovieListBean.DataBean.HotBean>>() {
    @Override
    public void subscribe(final ObservableEmitter<List<HotMovieListBean.DataBean.HotBean>> e) throws Exception {
    RetrofitClient
    .getInstance()
    .api()
    .getHotMovieList( headline, movieIds)
    .flatMap(new Function<HotMovieListBean, ObservableSource<HotMovieListBean.DataBean.MoviesBean>>() {
    @Override
    public ObservableSource<HotMovieListBean.DataBean.MoviesBean> apply(@NonNull HotMovieListBean hotMovieListBean) throws Exception {
    if (hotMovieListBean.getData().getMovies().size() > 0) {
    return Observable.fromIterable(hotMovieListBean.getData().getMovies());
    }
    return Observable.error(new Exception("没有更多数据"));
    }
    })
    //map操作符将数据转换为需要的数据
    .map(new Function<HotMovieListBean.DataBean.MoviesBean, HotMovieListBean.DataBean.HotBean>() {
    @Override
    public HotMovieListBean.DataBean.HotBean apply(@NonNull HotMovieListBean.DataBean.MoviesBean moviesBean) throws Exception {
    HotMovieListBean.DataBean.HotBean hotBean = new HotMovieListBean.DataBean.HotBean();
    hotBean.setBoxInfo(moviesBean.getBoxInfo());
    hotBean.setCat(moviesBean.getCat());
    hotBean.setCivilPubSt(moviesBean.getCivilPubSt());
    hotBean.setId(moviesBean.getId());
    hotBean.setShowInfo(moviesBean.getShowInfo());//播放场次
    hotBean.setSc(moviesBean.getSc());//得分
    hotBean.setNm(moviesBean.getNm());//片名
    hotBean.setVer(moviesBean.getVer());//3D标签
    hotBean.setScm(moviesBean.getScm());//描述
    hotBean.setPreSale(moviesBean.getPreSale());//是否预售
    hotBean.setWish(moviesBean.getWish());//期待观影人数
    hotBean.setImg(moviesBean.getImg());
    return hotBean;
    }
    })
    .toList()
    .subscribe(new Consumer<List<HotMovieListBean.DataBean.HotBean>>() {
    @Override
    public void accept(@NonNull List<HotMovieListBean.DataBean.HotBean> hotBeen) throws Exception {
    e.onNext(hotBeen);
    e.onComplete();
    }
    }, new Consumer<Throwable>() {
    @Override
    public void accept(@NonNull Throwable throwable) throws Exception {
    e.onError(throwable);
    }
    });
    }
    });

    }
    }

  • 5 我们在HotMovieListPresenter中将数据添加到容器中并为其转换线程

  • addSubcribeUntilDestory(hotMovieListManager.getHotMovieList(limit)
    .compose(SchedulersCompat.<HotMovieListBean>applyIoSchedulers())
    .subscribe(new Consumer<HotMovieListBean>() {
    @Override
    public void accept(@NonNull HotMovieListBean hotMovieListBean) throws Exception {
    mView.addMovieIds(hotMovieListBean.getData().getMovieIds());
    mView.addHotMovieList(hotMovieListBean.getData().getHot());
    }
    }, new Consumer<Throwable>() {
    @Override
    public void accept(@NonNull Throwable throwable) throws Exception {
    Logger.e(throwable.getMessage());
    mView.showError(ErrorHanding.handleError(throwable));

                  }
              }, new Action() {
                  @Override
                  public void run() throws Exception {
                      mView.showContent();
                  }
              }));
    

线程的转换类

public class SchedulersCompat {
public static <T>ObservableTransformer<T,T> applyIoSchedulers(){
    return new ObservableTransformer<T, T>() {
        @Override
        public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
            return upstream.subscribeOn(Schedulers.io())
                   .observeOn(AndroidSchedulers.mainThread());
        }
    };
}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容