项目中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中添加权限

      
      
      
      
      
      
      
    
  • 我们编写一个请求接口,例如:

       @GET("mmdb/movie/v3/list/hot.json")
       Observable 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 clz)

         public  T create(Class 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> getMoreMovieList(final int headline, final String movieIds) {
    return Observable.create(new ObservableOnSubscribe>() {
    @Override
    public void subscribe(final ObservableEmitter> e) throws Exception {
    RetrofitClient
    .getInstance()
    .api()
    .getHotMovieList( headline, movieIds)
    .flatMap(new Function>() {
    @Override
    public ObservableSource 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() {
    @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>() {
    @Override
    public void accept(@NonNull List hotBeen) throws Exception {
    e.onNext(hotBeen);
    e.onComplete();
    }
    }, new Consumer() {
    @Override
    public void accept(@NonNull Throwable throwable) throws Exception {
    e.onError(throwable);
    }
    });
    }
    });

    }
    }

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

  • addSubcribeUntilDestory(hotMovieListManager.getHotMovieList(limit)
    .compose(SchedulersCompat.applyIoSchedulers())
    .subscribe(new Consumer() {
    @Override
    public void accept(@NonNull HotMovieListBean hotMovieListBean) throws Exception {
    mView.addMovieIds(hotMovieListBean.getData().getMovieIds());
    mView.addHotMovieList(hotMovieListBean.getData().getHot());
    }
    }, new Consumer() {
    @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 ObservableTransformer applyIoSchedulers(){
    return new ObservableTransformer() {
        @Override
        public ObservableSource apply(@NonNull Observable upstream) {
            return upstream.subscribeOn(Schedulers.io())
                   .observeOn(AndroidSchedulers.mainThread());
        }
    };
}
}

你可能感兴趣的:(项目中Rxjava +Retrofit的使用)