項(xiàng)目中Rxjava +Retrofit的使用

  • 要構(gòu)建項(xiàng)目有送,最先我們需要的是導(dǎo)入包

      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中添加權(quán)限

      <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" />
    
  • 我們編寫一個(gè)請求接口堰汉,例如:

       @GET("mmdb/movie/v3/list/hot.json")
       Observable<HotMovieListBean> getHostList(@Query("limit") int limit);
    
  • 我們編寫一個(gè)Retrofit的網(wǎng)絡(luò)請求類 RetrofitClient

    1.該類一共分為五部:
    - 類的構(gòu)造函數(shù),初始化Retrofit完成其基本的配置
    -
    retrofit = new Retrofit.Builder()
    .baseUrl(mBaseUrl)
    .client(okHttpClient != null?okHttpClient:new OkHttpClient())
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build();
    -返回值為Retrofit的靜態(tài)方法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;
          }
    
    • 獲取經(jīng)過實(shí)例化的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;
         }
      
    • 構(gòu)建請求接口 create(Class<T> clz)

         public <T> T create(Class<T> clz){
              return retrofit.create(clz);
            } 
      
    • Api數(shù)據(jù)匹配

         public Api api(){
           return getInstance().create(Api.class);
          }
      
  • 2 值得注意的是我們在配置自定義的OkHttpClient時(shí)资昧,需要在Application的onCreate中進(jìn)行配置

  • 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);
    //超時(shí)時(shí)間
    builder.connectTimeout(15, TimeUnit.SECONDS);//15S連接超時(shí)
    builder.readTimeout(20, TimeUnit.SECONDS);//20s讀取超時(shí)
    builder.writeTimeout(20, TimeUnit.SECONDS);//20s寫入超時(shí)
    //錯(cuò)誤重連
    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();
    // 添加新的參數(shù)
    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請求參數(shù),ci為所在地參數(shù)
    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 在具體的項(xiàng)目中核芽,我們需要去請求數(shù)據(jù)耘斩,值得注意的時(shí)我們在獲取上拉刷新數(shù)據(jù)時(shí)顺少,我們需要對(duì)這些數(shù)據(jù)進(jìn)行一些特別的處理,由于我們解析得到的數(shù)據(jù)就具有兩個(gè)不同的實(shí)體倦始,但是唐門之間存在聯(lián)系斗遏,所以我們我們需要先使用flatMap將兩個(gè)類轉(zhuǎn)換一下之間的數(shù)據(jù)類型,并返回一個(gè)Observable對(duì)象鞋邑,然后在使用map方法見這個(gè)實(shí)體中我們需要使用到的數(shù)據(jù)進(jìn)行轉(zhuǎn)換诵次,代碼如下:

  • 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("沒有更多數(shù)據(jù)"));
    }
    })
    //map操作符將數(shù)據(jù)轉(zhuǎn)換為需要的數(shù)據(jù)
    .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標(biāo)簽
    hotBean.setScm(moviesBean.getScm());//描述
    hotBean.setPreSale(moviesBean.getPreSale());//是否預(yù)售
    hotBean.setWish(moviesBean.getWish());//期待觀影人數(shù)
    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中將數(shù)據(jù)添加到容器中并為其轉(zhuǎn)換線程

  • 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();
                  }
              }));
    

線程的轉(zhuǎn)換類

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());
        }
    };
}
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市枚碗,隨后出現(xiàn)的幾起案子逾一,更是在濱河造成了極大的恐慌,老刑警劉巖肮雨,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遵堵,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)陌宿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門锡足,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人壳坪,你說我怎么就攤上這事舶得。” “怎么了爽蝴?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵沐批,是天一觀的道長。 經(jīng)常有香客問我霜瘪,道長珠插,這世上最難降的妖魔是什么惧磺? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任颖对,我火速辦了婚禮,結(jié)果婚禮上磨隘,老公的妹妹穿的比我還像新娘缤底。我一直安慰自己,他們只是感情好番捂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布个唧。 她就那樣靜靜地躺著,像睡著了一般设预。 火紅的嫁衣襯著肌膚如雪徙歼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天鳖枕,我揣著相機(jī)與錄音魄梯,去河邊找鬼。 笑死宾符,一個(gè)胖子當(dāng)著我的面吹牛酿秸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播魏烫,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼辣苏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了哄褒?” 一聲冷哼從身側(cè)響起稀蟋,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呐赡,沒想到半個(gè)月后退客,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罚舱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年井辜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绎谦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粥脚,死狀恐怖窃肠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情刷允,我是刑警寧澤冤留,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站树灶,受9級(jí)特大地震影響纤怒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜天通,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一泊窘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧像寒,春花似錦烘豹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至筷笨,卻和暖如春憔鬼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胃夏。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國打工轴或, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人构订。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓侮叮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悼瘾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子囊榜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容